項(xiàng)目和集合
1、 項(xiàng)目go on
1.1 任務(wù)目標(biāo)
1. 嘗試使用
????接口指定規(guī)范,完成數(shù)據(jù)展示過(guò)濾功能
????例如:
????????只要學(xué)生成績(jī)50分以上
????????只要學(xué)生年齡16歲以下...
????方法名要求
????????accept
2. 完成數(shù)據(jù)的字符串處理過(guò)程
????數(shù)據(jù) ==> 字符串 字符串 ==> 數(shù)據(jù)
1.2 使用接口完成按照條件過(guò)濾展示數(shù)據(jù)的方式
分析需要完成的方法
????該方法是在遍歷展示學(xué)生數(shù)據(jù)的過(guò)程中完成的。存在一個(gè)判斷
????for(遍歷保存數(shù)據(jù)的數(shù)組) {
????????if (條件過(guò)濾) {
????????????展示
????????}
????}
????返回值類型:
????????boolean
????方法名:
????????accept
????形式參數(shù)列表:
????????一個(gè)Student學(xué)生類對(duì)象
interface StudentFilter {
????boolean accept(Student stu);
}
package com.qfedu.student.system.filter;
import com.qfedu.student.system.entity.Student;
public interface StudentFilter {
????/**
????* 判斷一個(gè)Student類對(duì)象是否能夠滿足條件,滿足條件返回true,否則返回false
????* 條件判斷由接口實(shí)現(xiàn)類完成
????*
????* @param student Student類對(duì)象
????* @return 滿足條件返回true,不滿足返回false
????*/
????boolean accept(Student student);
}
package com.qfedu.student.system.filter.impl;
import com.qfedu.student.system.entity.Student;
import com.qfedu.student.system.filter.StudentFilter;
public class StudentFilterImpl implements StudentFilter {
????@Override
????public boolean accept(Student student) {
????????return student.getScore() > 50 && student.getAge() > 100;
????}
}
1.3 完成數(shù)據(jù)的字符串處理過(guò)程
1.3.1 對(duì)于數(shù)據(jù)處理的基本理念
????程序數(shù)據(jù) ==> 字符串 ==> 文件
????文件 ==> 字符串 ==> 程序數(shù)據(jù)
1.3.2 程序數(shù)據(jù)==> 字符串
Student [id=11, name=騷磊, age=166, gender=男, score=60]
數(shù)據(jù)
????11 騷磊 166 男 60
????每一個(gè)數(shù)據(jù)都有對(duì)應(yīng)的指向性
數(shù)據(jù)對(duì)應(yīng)的名稱不需要保存
????但是需要約束好數(shù)據(jù)的存儲(chǔ)和解析規(guī)范。
????類似于真實(shí)開發(fā)場(chǎng)景中的接口概念,也就是規(guī)范化數(shù)據(jù)傳輸格式?。。?/p>
保存數(shù)據(jù)
????11 騷磊 166 男 60 ==> 11,騷磊,166,男,60 ==> String
????+ 萬(wàn)能膠水
/**
* 獲取Student類對(duì)象中數(shù)據(jù)的字符串形式? ? ?
*? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
* @return Student信息字符串
*/? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
public String getStudentData() {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????return id + "," + name + "," + age + "," + gender + "," + score;
}
1.3.3 字符串 ==> 程序數(shù)據(jù)
字符串
????11,騷磊,166,男,60
????==> Student 對(duì)象
1. split(",")
????==> String類型的數(shù)組{"11", "騷磊", "166", "男", "60"}
2. id age score ==> int類型
3. 包裝類
????Byte Short Integer Long Float Double Character Boolean
????【解析方法】
????存在將字符串?dāng)?shù)據(jù) ==> 對(duì)應(yīng)類型的方法。
方法
????目前該方法存放在Student類內(nèi),暫時(shí)存放,后期考慮完成一個(gè)數(shù)據(jù)處理類(DAO)
????方法權(quán)限修飾符
????public? √
是否需要使用static修飾
????靜態(tài)成員方法?
????????通過(guò)類名直接調(diào)用,做成一個(gè)工具方法,操作更加方便,擺脫類對(duì)象約束
????返回值類型:
????????Student
????方法名:
????????parseStudent
????形式參數(shù)列表:
????????String str
方法聲明:
????public static Student parseStudent(String str);
/**
* 解析學(xué)生信息字符串,轉(zhuǎn)換成一個(gè)Student類對(duì)象返回? ? ? ? ? ? ? ? ? ? ? ?
*? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
* @param str 包含Student信息指定格式字符串? ? ? ? ? ? ? ? ? ? ?
* @return Student類對(duì)象? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
*/? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
public static Student parseStudent(String str) {? ? ?
????// "11,騷磊,166,男,60"? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????// 1. split 按照逗號(hào)分隔? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????String[] split = str.split(",");? ? ? ? ? ? ? ? ?
????// {"11","騷磊","166","男","60"}? ? ? ? ? ? ? ? ? ?
????// Integer.parseInt(String str) 字符串 ==> int類型數(shù)據(jù)?
????int id = Integer.parseInt(split[0]);? ? ? ? ? ? ?
????String name = split[1];? ? ? ? ? ? ? ? ? ? ? ? ?
????int age = Integer.parseInt(split[2]);? ? ? ? ? ?
????char gender = split[3].charAt(0);? ? ? ? ? ? ? ?
????int score = Integer.parseInt(split[4]);? ? ? ? ?
????????/*? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????Float.parseFloat(s)? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????Double.parseDouble(s)? ? ? ? ? ? ? ? ? ? ? ? ? ?
????Boolean.parseBoolean(s)? ? ? ? ? ? ? ? ? ? ? ? ?
????*/? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????return new Student(id, name, age, gender, score);
}
2、集合【重點(diǎn)】
2.1 集合概述
目前代碼中對(duì)于多個(gè)數(shù)據(jù)處理過(guò)程中,我們采用的方式是數(shù)組方式。
????數(shù)組操作存在的問題:
????????1. 復(fù)用度差?。?!
????????????目前對(duì)于數(shù)據(jù)操作有且只能支持一個(gè)數(shù)據(jù)類型,一旦需要操作其他類型,全部重構(gòu),從頭來(lái)過(guò)
????????2. 空間固定?。?!
????????????數(shù)組的空間一旦在創(chuàng)建過(guò)程中確定,空間無(wú)法修改。
????????3. 方法較少?。?!
????????????add remove modify get 。。。
????????????自己寫的?。?!方法自己實(shí)現(xiàn),體驗(yàn)不好?。?!Java中對(duì)于數(shù)組操作沒有提供太多的有效方法
以上問題集合都可以解決?。?!
????1. 復(fù)用性,沒有問題?。?!
????集合創(chuàng)建采用了泛型模式,可以用戶指定任意類型操作!?。〖葷M足普適性,又滿足數(shù)據(jù)類型一致化要求
????2. 空間在合理范圍以內(nèi)自行擴(kuò)展,不需要考慮容量問題
????3. 方法很多?。?!操作性很好!??!
2.2 集合架構(gòu) 【重點(diǎn)】
interface Collection<E> Java中所有集合的總接口
--| interface List<E> List接口,數(shù)據(jù)存儲(chǔ)可重復(fù),有序。
----| class ArrayList<E>
????重點(diǎn) 可變長(zhǎng)數(shù)組
----| class LinkedList<E>
????重點(diǎn) 雙向鏈表模式
----| class Vector<E>
????線程安全的可變長(zhǎng)數(shù)組
--| interface Set<E> Set接口,數(shù)據(jù)存儲(chǔ)不可以重復(fù),無(wú)序
----| HashSet<E>
????底層存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)是一個(gè)哈希表,存儲(chǔ)效率,查詢效率極高?。。?/p>
----| TreeSet<E>
????底層存儲(chǔ)數(shù)據(jù)的結(jié)構(gòu)是一個(gè)平衡二叉樹結(jié)構(gòu),要求數(shù)據(jù)必須有比較方式?。?!
2.3 Collection接口下的常用方法【重點(diǎn)】
增:
????boolean add(E e)
????????添加當(dāng)前集合約束的指定數(shù)據(jù)類型到當(dāng)前集合中
????boolean addAll(Collection<? extends E> c);
????????添加另一個(gè)集合到當(dāng)前集合中,要求添加集合中保存的元素必須是當(dāng)前集合中保存元素本身或者其子類對(duì)象 【泛型的上限】
????class Dog extends Animal
????class Cat extends Animal
????class Tiger extends Animal
刪:
????boolean remove(Object obj);
????????刪除集合中的指定元素,刪除成功返回true,未找到指定元素,無(wú)法刪除返回false,并且在多個(gè)元素的情況下,刪除找到的第一個(gè)元素。
????boolean removeAll(Collection<?> c);
????????在當(dāng)前集合中刪除兩個(gè)集合的交集
????boolean retainAll(Collection<?> c);
????????在當(dāng)前集合中保留兩個(gè)集合的交集
????void clear();
????????清空整個(gè)集合中的所有元素
查:
????int size();
????????有效元素個(gè)數(shù)
????boolean isEmpty();
????????判斷當(dāng)前集合是否為空,是否存在有效元素
????boolean contains(Object obj);
????????判斷指定元素是否在當(dāng)前集合中存在
????boolean containsAll(Collection<?> c);
????????判斷傳入的參數(shù)集合是不是當(dāng)前集合的子集合
????Object[] toArray();
???????返回集合中所有保存元素的Object類型數(shù)組
2.4 泛型上限
問題:
????<? extends E>
????class Animal
????--| class Dog extends Animal
????--| class Cat extends Animal
????--| class Tiger extends Animal
????? 替代Dog Tiger
????E ==> Animal
? 是泛型的通配符
package com.qfedu.a_collection;
import java.util.ArrayList;
import java.util.Collection;
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
class Flower {}
/*
* 泛型上限演示
*/
public class Demo3 {
????public static void main(String[] args) {
????????Collection<Animal> c1 = new ArrayList<Animal>();
????????Collection<Dog> c2 = new ArrayList<Dog>();
????????Collection<Cat> c3 = new ArrayList<Cat>();
????????Collection<Flower> c4 = new ArrayList<Flower>();
????????Collection<Object> c5 = new ArrayList<Object>();
????????/*
????????* 當(dāng)前方法所需的參數(shù)類型是Collection<? extends Animal>
????????*
????????* 要求參數(shù)是一個(gè)Collection集合
????????* 要求Collection集合中保存的元素是Animal本身或者其子類對(duì)象
????????*/
????????c1.addAll(c1);
????????c1.addAll(c2);
????????c1.addAll(c3);
????????/*
????????* c4 對(duì)應(yīng)的數(shù)據(jù)類型是Collection<Flower>
????????* 滿足當(dāng)前方法所需數(shù)據(jù)類型必須是Collection集合,但是不滿足
????????* 當(dāng)前集合中保存元素是Animal本身或者其子類對(duì)象的需求。參數(shù)錯(cuò)誤。
????????*/
????????// c1.addAll(c4);
????????/*
????????* c5 對(duì)應(yīng)的數(shù)據(jù)類型是Collection<Object>
????????* 滿足參數(shù)要求為Collection集合,但是存儲(chǔ)元素是Object類型
????????* 不是Animal的子類
????????*/
????????// c1.addAll(c5);
????????c1.add(new Animal());
????????c1.add(new Dog());
????????c1.add(new Cat());
????????System.out.println(c1);
????}
}
2.5 ? 泛型通配符
boolean removeAll(Collection<?> c);
????在當(dāng)前集合中刪除兩個(gè)集合的交集
boolean retainAll(Collection<?> c);
????在當(dāng)前集合中保留兩個(gè)集合的交集
boolean containsAll(Collection<?> c);
????判斷傳入的參數(shù)集合是不是當(dāng)前集合的子集合
????? 在當(dāng)前情況下描述的場(chǎng)景為,不限制傳入?yún)?shù)Collection集合中的保存元素。
????這里只要求參數(shù)類型是Collection,里面保存元素?zé)o所謂
2.6 集合使用迭代器
2.6.1 迭代器概述和操作模式
迭代器是操作集合中元素的第二種方式,后期可以延展使用到很多地方,并且存在一個(gè)升級(jí)版內(nèi)容。【增強(qiáng)for循環(huán)】
迭代器和集合本身有著密切關(guān)系,首先迭代器的獲取,就是通過(guò)集合對(duì)象得到對(duì)應(yīng)當(dāng)前集合的迭代器。
獲取迭代器方法:
????Iterator<E> iterator();
????????獲取迭代器對(duì)象,泛型對(duì)應(yīng)的具體數(shù)據(jù)類型和集合中約束的泛型具體數(shù)據(jù)類型一致。
迭代器操作使用到的方法:
????boolean hasNext();
????????判斷當(dāng)前集合中是否可以繼續(xù)得到元素,繼續(xù)遍歷。
????E next();
????????1. 獲取迭代器當(dāng)前指向的元素
????????2. 將迭代器指向下一個(gè)元素
????void remove();
????????刪除通過(guò)next方法獲取到元素
????????【注意事項(xiàng)】
????????1. remove方法只能刪除next方法獲取到元素
????????2. remove方法只能在next方法之后執(zhí)行,且不能跨過(guò)一個(gè)next執(zhí)行
????????3. 沒有next不能使用remove
2.6.2 使用迭代器操作集合
package com.qfedu.b_iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
* 迭代器操作
*/
public class Demo1 {
????public static void main(String[] args) {
????????Collection<String> c = new ArrayList<String>();
????????c.add("雪花純生");
????????c.add("修道院啤酒");
????????c.add("1664");
????????c.add("泰山精釀");
????????c.add("時(shí)光精釀");
????????System.out.println(c);
????????/*
????????* 獲取對(duì)應(yīng)當(dāng)前集合的迭代器對(duì)象
????????* 集合中保存元素是什么類型,迭代器操作元素就是什么類型
????????*
????????* 迭代器在獲取的過(guò)程中,默認(rèn)指向集合中的第一個(gè)元素
????????*/
????????Iterator<String> iterator = c.iterator();
????????System.out.println("hasNext()方法演示:" + iterator.hasNext());
????????System.out.println("next()方法演示:" + iterator.next());
????????System.out.println("next()方法演示:" + iterator.next());
????????System.out.println("remove()執(zhí)行");
????????// 指向迭代器remove方法
????????iterator.remove();
????????// iterator.remove();
????????System.out.println(c);
????}
}
package com.qfedu.b_iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo2 {
????public static void main(String[] args) {
????????Collection<String> c = new ArrayList<String>();
????????c.add("雪花純生");
????????c.add("修道院啤酒");
????????c.add("1664");
????????c.add("泰山精釀");
????????c.add("時(shí)光精釀");
????????/*
????????* 獲取當(dāng)前集合的迭代器對(duì)象
????????*/
????????Iterator<String> iterator = c.iterator();
????????while (iterator.hasNext()) {
????????????String string = iterator.next();
????????????System.out.println(string);
????????????iterator.remove();
????????}
????????System.out.println(c);
????????System.out.println(c.isEmpty());
????}
}
2.6.3 迭代器和集合引用數(shù)據(jù)類型變量沖突問題 【難點(diǎn)】
package com.qfedu.b_iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo3 {
????public static void main(String[] args) {
????????Collection<String> c = new ArrayList<String>();
????????c.add("雪花純生");
????????c.add("修道院啤酒");
????????c.add("1664");
????????c.add("泰山精釀");
????????c.add("時(shí)光精釀");
????????/*
????????* 根據(jù)當(dāng)前集合,獲取對(duì)應(yīng)的迭代器對(duì)象
????????*
????????* 得到的迭代器對(duì)象會(huì)依據(jù),當(dāng)前集合中的所有元素進(jìn)行一個(gè)規(guī)劃操作。
????????* 迭代器對(duì)于整個(gè)集合中的元素都是存在預(yù)期。
????????*/
????????Iterator<String> iterator = c.iterator();
????????/*
????????* 迭代器遍歷,利用迭代器的特征進(jìn)行遍歷操作
????????*/
????????while (iterator.hasNext()) {
????????// 獲取每一個(gè)迭代器指向元素,并且展示
????????????String string = iterator.next();
????????????System.out.println(string);
????????????/*
????????????* 通過(guò)集合對(duì)象本身刪除1664,對(duì)于迭代器而言,一臉懵逼,原本的規(guī)劃
????????????* 沒有了?。?!并且集合沒有告知迭代器數(shù)據(jù)發(fā)生了改變,迭代器繼續(xù)按照
????????????* 原本的規(guī)劃路徑操作,保存!?。?/p>
????????????*
????????????* 對(duì)于集合在內(nèi)存中占用的空間而言
????????????* 1. 集合對(duì)應(yīng)的引用數(shù)據(jù)類型變量可以操作對(duì)應(yīng)空間
????????????* 2. 迭代器可以操作對(duì)應(yīng)的空間
????????????*
????????????* 對(duì)于集合和迭代器而言,【集合在內(nèi)存中占用的空間】共享資源,在操作
????????????* 共享資源過(guò)程中,我們要多多考慮共享資源的沖突問題。
????????????* 后面課程中會(huì)講到【多線程】
????????????*/
????????????c.remove("1664");
????????}
????????/*
????????Exception in thread "main" java.util.ConcurrentModificationException
????????at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
????????at java.util.ArrayList$Itr.next(ArrayList.java:859)
????????at com.qfedu.b_iterator.Demo3.main(Demo3.java:30)
????????*/
????}
}