學習目標
能夠說出集合與數組的區別數組:1.是引用數據類型的一種2.可以存儲多個元素3.數組的長度是固定的 int[] arr1 = new int[10]; int[] arr2 = {1,2,3};4.數組即可以存儲基本類型的數據,又可以存儲引用數據類型的數據int[],double[],String[],Student[]集合:1.是引用數據類型的一種2.可以存儲多個元素3.集合的長度是可以變化的(可以往集合中添加元素,刪除集合中的元素)4.只能存儲引用數據類型的數據ArrayList<int> 錯誤 ArrayList<Integer> ArrayList<Student>
能夠使用Collection集合的常用功能(重點)public boolean add(E e) : 把給定的對象添加到當前集合中 。public boolean remove(E e) : 把給定的對象在當前集合中刪除。public boolean contains(Object obj) : 判斷當前集合中是否包含給定的對象。public boolean isEmpty() : 判斷當前集合是否為空。public int size() : 返回集合中元素的個數。public Object[] toArray() : 把集合中的元素,存儲到數組中public void clear() :清空集合中所有的元素。
能夠使用迭代器對集合進行取元素(重點)//1.創建集合對象,往集合中添加元素Collection<String> coll = new ArrayList<>();//Collection<String> coll = new HashSet<>();coll.add("詹姆斯");coll.add("姚明");coll.add("科比");coll.add("喬丹");coll.add("艾弗森");//2.使用Collection接口中的方法iterator,獲取迭代器的實現類對象Iterator<String> it = coll.iterator();//3.使用迭代器對象Iterator中的方法hasNext和next遍歷集合while(it.hasNext()){String s = it.next();System.out.println(s);}
能夠使用增強for循環遍歷集合和數組(重點)for(集合|數組中元素的數據類型 變量名: 集合|數組){sout(變量名);}int[] arr = {1,2,3};for(int i : arr){sout(i);}ArrayList<String> list = new ArrayList<>();list.add("a");list.add("b");for(String s : list){sout(s);}
能夠理解泛型上下限泛型的上限限定: ? extends E ==>傳遞的未知類型?只能是E的子類或者本身泛型的下限限定: ? super E ==>傳遞的未知類型?只能是E的父類或者本身
能夠闡述泛型通配符的作用泛型的通配符: ? 可以接收任意的數據類型
能夠說出常見的數據結構棧,隊列,數組,鏈表,紅黑樹
能夠說出數組結構特點查詢快,增刪慢
能夠說出棧結構特點先進后出
能夠說出隊列結構特點先進先出
能夠說出單向鏈表結構特點查詢慢,增刪快
第一章 Collection集合
1.集合和數組的區別
數組:
1.是引用數據類型的一種
2.可以存儲多個元素
3.數組的長度是固定的 int[] arr1 = new int[10]; int[] arr2 = {1,2,3};
4.數組即可以存儲基本數據類型的數據,又可以存儲引用數據類型的數據 int[] double[] String[] Student[]
集合:
1.是引用數據類型的一種
2.可以存儲多個元素
3.集合的長度是可以變化的(添加元素,刪除集合中的元素)
4.集合只能存儲引用數據類型的數據
ArrayList<int> 錯誤 ArrayList<Integer> ArrayList<Student> ArrayList<String>正確
2.集合常用類的繼承體系
3.Collection常用功能(重點)
package com.itheima.demo01Collection;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;/*java.util.Collection<E>Collection 層次結構 中的根接口。Collection 表示一組對象,這些對象也稱為 collection 的元素。一些 collection 允許有重復的元素,而另一些則不允許。一些 collection 是有序的,而另一些則是無序的。Collection接口中定義了所有單列集合共性的成員方法,所有的實現類都可以使用public boolean add(E e) : 往集合中添加元素public boolean remove(E e) : 移除集合中指定的元素public boolean contains(Object obj) : 判斷當前集合中是否包指定的元素。public boolean isEmpty() : 判斷當前集合是否為空。public int size() : 返回集合中元素的個數。獲取集合的長度public Object[] toArray() : 把集合中的元素,存儲到數組中public void clear() :清空集合中所有的元素。*/
public class Demo01Collection {public static void main(String[] args) {//創建Collection集合對象:多態(接口指向實現類對象,擴展性強)Collection<String> coll = new ArrayList<>();coll = new HashSet<>();/*public boolean add(E e) : 往集合中添加元素返回值:boolean添加成功,返回true,添加元素百分之百會成功添加失敗,返回false*/boolean b1 = coll.add("張三");System.out.println("b1:"+b1);//b1:truecoll.add("李四");coll.add("王五");coll.add("張三");coll.add("趙六");coll.add("田七");System.out.println(coll);//[張三, 李四, 王五, 張三, 趙六, 田七] 打印對象名,不是地址值,重寫了Object類的toString方法/*public boolean remove(E e) : 移除集合中指定的元素返回值:boolean集合中存儲指定的元素,移除元素,返回true;如果集合移除的元素有相同的,只會移除第一個集合中不存在指定的元素,remove方法對集合沒有影響,返回false*/boolean b2 = coll.remove("張三");System.out.println("b2:"+b2);//b2:trueSystem.out.println(coll);//[李四, 王五, 張三, 趙六, 田七]boolean b3 = coll.remove("趙四");System.out.println("b3:"+b3);//b3:falseSystem.out.println(coll);//[李四, 王五, 張三, 趙六, 田七]/*public boolean contains(Object obj) : 判斷當前集合中是否包指定的元素。返回值:boolean集合中包含指定的元素,返回true集合中不包含指定的元素,返回false*/boolean b4 = coll.contains("田七");System.out.println("b4:"+b4);//b4:trueboolean b5 = coll.contains("胡歌");System.out.println("b5:"+b5);//b5:false/*public boolean isEmpty() : 判斷當前集合是否為空。返回值:boolean集合中沒有元素,是空的,返回true集合中有元素,不是空的,返回false*/boolean b6 = coll.isEmpty();System.out.println("b6:"+b6);//b6:false/*public int size() : 返回集合中元素的個數。獲取集合的長度*/int size = coll.size();System.out.println("size:"+size);//size:5/*public Object[] toArray() : 把集合中的元素,存儲到數組中*/Object[] arr = coll.toArray();System.out.println(Arrays.toString(arr));//[李四, 王五, 張三, 趙六, 田七]/*public void clear() :清空集合中所有的元素。注意:此方法只是清空集合中的元素,不是刪除集合;清空完集合還存在,還可以使用*/coll.clear();System.out.println(coll);//[]System.out.println(coll.size());//0System.out.println(coll.isEmpty());//true}
}
第二章 Iterator迭代器
1.迭代器的概述
/*迭代器:是一種通用取出集合中元素的方式迭代器的由來:集合有很多種,每種集合的數據結構不同(數組,鏈表,哈希表...),集合取出元素的方式也不同我們不可能為每種集合都定義一種取出元素的方式,浪費所以我們可以使用迭代器,是集合通用的取出元素的方式迭代器的原理:判斷集合中還有沒有元素,有就取出來;再判斷集合中還有沒有元素,有再取出來;一直判斷到集合中沒有元素為止,這種取出元素的方式叫迭代------------------------------------------------------------------------------------java.util.Iterator<E>接口:對 collection 進行迭代的迭代器。Iterator接口的常用方法:boolean hasNext() 如果仍有元素可以迭代,則返回 true。判斷集合中還沒有沒有元素;有返回true,沒有返回falseE next() 返回迭代的下一個元素。 取出集合中的元素------------------------------------------------------------------------------------Iterator是一個接口無法創建對象使用,使用Iterator接口的實現類對象,Iterator接口的實現類對象是每個集合的內部類(了解)我們可以使用Collection接口中的方法iterator獲取迭代器Iterator接口的實現類對象Iterator<E> iterator() 返回在此 collection 的元素上進行迭代的迭代器。注意:我們無需關注iterator方法返回的是接口的哪個實現類對象,我們只需要會使用Iterator接口來接收這個實現類對象即可(多態)*/
2.迭代器的基本使用(重點)
/*迭代器的使用步驟(重點):1.創建集合對象,往集合中存儲元素2.使用Collection接口中的方法iterator,獲取迭代器接口的實現類對象3.使用迭代器對象Iterator接口中的方法hasNext和next遍歷集合*/
public class Demo01Iterator {public static void main(String[] args) {//1.創建集合對象,往集合中存儲元素Collection<String> coll = new ArrayList<>();coll.add("詹姆斯");coll.add("姚明");coll.add("科比");coll.add("喬丹");coll.add("艾弗森");/*2.使用Collection接口中的方法iterator,獲取迭代器接口的實現類對象注意:迭代器Iterator是有泛型的,迭代的泛型跟著集合走,集合是什么泛型,迭代器就是什么泛型*///多態 接口 = 實現類對象Iterator<String> it = coll.iterator();//3.使用迭代器對象Iterator接口中的方法hasNext和next遍歷集合/*我們發現使用迭代器取出元素是一個重復的過程,所以我們可以使用循環優化代碼不知道集合中有多個元素,一般使用while循環while循環結束的條件:it.hasNext方法返回false*/while (it.hasNext()){//判斷集合中還有沒有元素//有元素,取出元素String s = it.next();System.out.println(s);}System.out.println("-----------------------------");//注意:迭代器只能使用一次,想要在遍歷元素,必須重新獲取一個新的迭代器for(Iterator<String> it2 = coll.iterator();it2.hasNext();){String s = it2.next();System.out.println(s);}/*boolean b = it.hasNext();System.out.println(b);//trueString s = it.next();System.out.println(s);//詹姆斯b = it.hasNext();System.out.println(b);//trues = it.next();System.out.println(s);//姚明b = it.hasNext();System.out.println(b);//trues = it.next();System.out.println(s);//科比b = it.hasNext();System.out.println(b);//trues = it.next();System.out.println(s);//喬丹b = it.hasNext();System.out.println(b);//trues = it.next();System.out.println(s);//艾弗森b = it.hasNext();System.out.println(b);//false*///s = it.next();//沒有元素,就不能使用next方法獲取元素,在獲取元素會拋出沒有元素異常:NoSuchElementException}
}
3.迭代器的執行原理
4.迭代器的并發修改異常(面試)
package com.itheima.demo02Iterator;import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;/*迭代器的并發修改異常:在使用迭代器遍歷集合的過程中,對集合長度進行了修改,迭代器就會拋出并發修改異常ConcurrentModificationException注意:1.并發:遍歷和修改同時進行2.修改:修改集合的長度(添加元素,刪除元素)解決方案:1.遍歷集合的同時,不修改集合的長度2.Iterator接口有一個子接口叫ListIterator在ListIterator接口定義了往集合中添加元素的方法public interface ListIterator<E>extends Iterator<E>void add(E e) 迭代器中往集合添加元素的方法void remove() 刪除的是next方法取出的元素注意:1.如果使用迭代器中的add|remove方法,往集合中添加|刪除元素就相當于集合和迭代器商量好了,可以往集合中添加|刪除元素,迭代器就不會拋出并發修改異常了2.ListIterator迭代器只能遍歷List接口下的集合(ArrayList,LinkedList),不能遍歷Set接口下的集合(HashSet,LinkedHashSet)*/
public class Demo02Iterator {public static void main(String[] args) {//創建集合對象,往集合中添加元素ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add(null);list.add("bbb");list.add("ccc");list.add("ddd");list.add("eee");//使用迭代器遍歷list集合//使用集合中的方法iterator獲取迭代器接口的實現類對象Iterator<String> it = list.iterator();//使用Iterator迭代器中的方法hasNext和next遍歷集合while (it.hasNext()){String s = it.next();System.out.println(s);/*需求:增加一個判斷,如果取出的元素是"ccc"就給集合添加一個新的元素"itcast"編程技巧:使用equals方法判斷的時候,一般都把已知的值寫在前邊,防止空指針異常*/if("ccc".equals(s)){//list.add("itcast");//ConcurrentModificationException//list.remove("ddd");//ConcurrentModificationException}}System.out.println("--------------第二種解決并發修改異常的方法------------------------");//使用List接口中的方法listIterator獲取ListIterator迭代器接口的實現類對象//ListIterator<E> listIterator() 返回此列表元素的列表迭代器(按適當順序)。ListIterator<String> lit = list.listIterator();//使用迭代器中的方法hasNext和next遍歷集合while (lit.hasNext()){String s = lit.next();System.out.println(s);/*需求:增加一個判斷,如果取出的元素是"ccc"就給集合添加一個新的元素"itcast"*/if("ccc".equals(s)){//lit.add("itcast");//使用迭代器中的add方法,往集合中添加元素lit.remove();//刪除的是next方法取出的元素}}//遍歷的過程中是不會打印出新添加的元素的,遍歷之后在打印就可以看到了System.out.println(list);//[aaa, null, bbb, ccc, itcast, ddd, eee] [aaa, null, bbb, ddd, eee]}
}
5.迭代器的實現類是每個集合的內部類(了解)
6.增強for循環(重點)
注意:
? 增強for循環底層是一個迭代器,所以在使用增強for循環遍歷的時候,不能對集合的長度進行修改,否則會拋出并發修改異常
package com.itheima.demo02Iterator;import java.util.ArrayList;/*增強for循環(重點)是JDK1.5之后出現的新特性使用for循環的方式,對迭代器進行了簡化增強for循環內部就是一個迭代器,對迭代器進行了封裝Collection接口有一個父接口叫Iterablepublic interface Collection<E> extends Iterable<E>java.lang.Iterable<T>接口實現這個接口允許對象成為 "foreach" 語句的目標。Collection接口繼承了Iterable接口,所以可以使用增強for循環Collection接口所有的實現類,都可以使用增強for循環(ArrayList,LinkedList,HashSet...)------------------------------------------------------------增強for循環的格式:重點for(集合|數組中元素的類型 變量名 : 集合名|數組名){sout(變量名);}*/
public class Demo03Foreach {public static void main(String[] args) {show03();}/*使用增強for循環遍歷集合快捷鍵:數組名|集合名.for 增強for*/private static void show03() {ArrayList<Student> list = new ArrayList<>();list.add(new Student("張三",18));list.add(new Student("李四",19));list.add(new Student("王五",20));for (Student s : list) {//注意:增強for循環底層就是一個迭代器,在遍歷的過程中不能修改集合的長度//list.add(new Student("趙六",18));//ConcurrentModificationExceptionSystem.out.println(s);}}/*使用增強for循環遍歷集合好處:可以在遍歷的過程中使用元素特有的方法*/private static void show02() {ArrayList<String> list = new ArrayList<>();list.add("aaa");list.add("bbbbbbb");list.add("cc");list.add("ddddd");for(String s : list){System.out.println(s+"-->"+s.length());}}/*使用增強for循環遍歷數組好處:格式簡單弊端:只能遍歷,不能修改數組中的元素*/private static void show01() {int[] arr1 = {1,2,3};//使用普通for循環遍歷數組for (int i = 0; i < arr1.length; i++) {arr1[i]*=2;System.out.println(arr1[i]);}System.out.println("arr1[0]:"+arr1[0]);System.out.println("--------------------");int[] arr2 = {1,2,3};for(int s : arr2){s *= 2;System.out.println(s);}System.out.println("arr2[0]:"+arr2[0]);}
}
第三章 泛型
1.泛型的概述
2.使用泛型的好處
package com.itheima.demo03Generic;import java.util.ArrayList;
import java.util.Iterator;/*java中的泛型:是一個偽泛型,在.java文件中有,但是.class文件中沒有*/
public class Demo01Generic {public static void main(String[] args) {show02();}/*使用泛型創建ArrayList集合對象好處:1.使用什么泛型就只能存儲什么類型的數據;避免向下轉型拋出類型轉換異常2.寫上泛型存儲的是什么類型,取出的就是什么類型,不用向下轉型,就可以使用特有的方法弊端:1.不能什么類型的數據都存儲*/private static void show02() {ArrayList<String> list = new ArrayList<>();list.add("aaa");//list.add(1);//使用迭代器遍歷list集合Iterator<String> it = list.iterator();while (it.hasNext()){String s = it.next();System.out.println(s+"-->"+s.length());}}/*不使用泛型創建ArrayList集合對象好處:不使用泛型,集合默認的數據類型就是Object類型,可以存儲任意數據類型的元素弊端:1.不能使用元素特有的方法(多態)2.在進行向下轉型的時候,容易引發類型轉換異常*/private static void show01() {ArrayList list = new ArrayList();list.add("aaa");list.add(1);//使用迭代器遍歷list集合Iterator it = list.iterator();while (it.hasNext()){//存儲的泛型是Object類型,取出元素類型也是Object類型Object obj = it.next();System.out.println(obj);/*多態 Object obj = "aaa"; 無法使用子類特有的方法*/if(obj instanceof String){String s = (String)obj;System.out.println(s.length());}}}
}
通過反編譯軟件,查看的class文件中,沒有泛型
3.定義和使用含有泛型的類
package com.itheima.demo04GenericClass;/*定義和使用含有泛型的類:模擬ArrayList集合當我們不知道使用什么類型的時候,就可以使用泛型,是一個未知的數據類型可以給泛型賦值任意的數據類型:Integer,Student,Person,String...定義格式:public class 類名<泛型>{類中使用數據類型的地方,都可以使用類上定義好的泛型}什么時候確定類上泛型的數據類型創建對象的時候,確定類上泛型的數據類型;對象使用什么類型,類的泛型就是什么類型*/
public class GenericClass<C> {private C name;public C getName() {return name;}public void setName(C name) {this.name = name;}
}
package com.itheima.demo04GenericClass;public class Demo01GenericClass {public static void main(String[] args) {//創建GenericClass對象,不使用泛型,類型默認就是Object類型GenericClass gc1 = new GenericClass();//創建GenericClass對象,泛型使用String類型GenericClass<String> gc2 = new GenericClass<>();gc2.setName("aaa");String name = gc2.getName();System.out.println(name);//創建GenericClass對象,泛型使用Integer類型GenericClass<Integer> gc3 = new GenericClass<>();gc3.setName(10);Integer in = gc3.getName();System.out.println(in);}
}
4.定義和使用含有泛型的方法(重點)
package com.itheima.demo05GenericMethod;/*定義和使用含有泛型的方法(重點)泛型需要定義在方法的修飾符和返回值類型之間定義格式:修飾符 <泛型> 返回值類型 方法名(參數類型-->使用泛型){方法體;}什么時候確定泛型的數據類型:調用方法,傳遞的參數是什么類型,方法的泛型就是什么類型*/
public class GenericMethod {//定義含有泛型的方法(重點)public <M> void method01(M m){System.out.println(m);}//定義含有泛型的靜態方法(了解)public static <S> void method02(S s){System.out.println(s);}//定義含有泛型的方法,返回值類型使用泛型(了解==>看源碼)public <AAA> AAA method03(AAA aaa){System.out.println(aaa);return aaa;}
}
package com.itheima.demo05GenericMethod;import com.itheima.demo02Iterator.Student;public class Demo01GenericMethod {public static void main(String[] args) {//創建GenericMethod對象GenericMethod gm = new GenericMethod();gm.method01(1);gm.method01("aaa");gm.method01(1.1);gm.method01(true);gm.method01('@');gm.method01(new Student("徐崢",45));System.out.println("------------------------------");//通過類名.方法名(參數)可以直接調用靜態方法GenericMethod.method02(1);GenericMethod.method02("aaa");GenericMethod.method02(1.1);System.out.println("------------------------------");Integer in = gm.method03(11);System.out.println(in);String abc = gm.method03("abc");System.out.println(abc);}
}
5.定義和使用含有泛型的接口
package com.itheima.demo06GenericInterface;/*定義含有泛型的接口*/
public interface GenericInterface<I> {//定義抽象方法,使用接口上的泛型,作為參數的類型public abstract void show(I i);
}
package com.itheima.demo06GenericInterface;/*含有泛型的接口:第一種使用方式定義一個類,實現含有泛型的接口,在實現接口的同時,指定接口泛型的數據類型格式:public class GenericInterfaceImpl1 implements GenericInterface<String>{重寫接口中的方法,使用指定的類型Stringpublic void show(String s) { }}public class GenericInterfaceImpl1 implements GenericInterface<Integer>{重寫接口中的方法,使用指定的類型Integerpublic void show(Integer integer) { }}*/
public class GenericInterfaceImpl1 implements GenericInterface<Integer>{@Overridepublic void show(Integer in) {System.out.println(in);}
}
package com.itheima.demo06GenericInterface;/*含有泛型的接口:第二種使用方式定義類實現含有泛型的接口,接口使用什么泛型,實現類就使用什么泛型實現類跟著接口走,就和定義一個含有泛型的類是一樣的格式:public class GenericInterfaceImpl2<I> implements GenericInterface<I>{重寫的方法使用接口上的泛型public void show(I i) { }}注意:創建對象的時候,確定泛型的數據類型;創建對象是什么數據類型,泛型就是什么數據類型*/
public class GenericInterfaceImpl2<I> implements GenericInterface<I>{@Overridepublic void show(I i) {System.out.println(i);}
}
package com.itheima.demo06GenericInterface;public class Demo01GenericInterface {public static void main(String[] args) {//創建GenericInterfaceImp1對象GenericInterfaceImpl1 gii1 = new GenericInterfaceImpl1();gii1.show(10);//創建GenericInterfaceImpl2對象GenericInterfaceImpl2<String> gii2 = new GenericInterfaceImpl2<>();gii2.show("aaa");GenericInterfaceImpl2<Double> gii3 = new GenericInterfaceImpl2<>();gii3.show(1.1);//匿名內部類new GenericInterface<String>(){@Overridepublic void show(String s) {System.out.println(s);}}.show("123123");}
}
6.泛型的通配符
package com.itheima.demo07Generic;import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;/*泛型的通配符?:代表可以接收任意的數據類型?已經由java定義好了,我們可以直接使用*/
public class Demo01Generic {public static void main(String[] args) {Collection<Integer> c1 = new ArrayList<>();c1.add(1);c1.add(2);Collection<String> c2 = new ArrayList<>();c2.add("aaa");c2.add("bbb");printCollction(c1);printCollction(c2);/*泛型的通配符只能作為方法參數的數據類型使用,不能創建對象作為數據類型使用*///ArrayList<?> list = new ArrayList<>();//list.add(1);//list.add("a");}/*定義一個方法,能遍歷任意數據類型的Collection集合1.Collection c:不寫泛型,默認就是Object類型2.可以使用泛型的通配符?,可以接收任意的數據類型*/public static void printCollction(Collection<?> c){//使用迭代器遍歷集合;集合的泛型是?,迭代器也是?Iterator<?> it = c.iterator();while (it.hasNext()){/*it.next方法取出的元素是什么類型是Object類型,Object可以接收任意數據類型的數據*/Object obj = it.next();System.out.println(obj);}}
}
package com.itheima.demo07Generic;import java.util.ArrayList;
import java.util.Collection;/*泛型通配符的高級使用泛型的通配符: ? 代表可以接收任意數據類型的數據泛型的上限限定: ? extends E==>傳遞的未知類型?只能使用E的子類或者是E本身泛型的下限限定: ? super E==>傳遞的未知類型?只能使用E的父類或者是E本身*/
public class Demo02Generic {public static void main(String[] args) {Collection<Integer> list1 = new ArrayList<Integer>();Collection<String> list2 = new ArrayList<String>();Collection<Number> list3 = new ArrayList<Number>();Collection<Object> list4 = new ArrayList<Object>();/*Integer extends Number extends ObjectString exntends Object*/getElement1(list1);//getElement1(list2);//報錯 String和Number沒有關系getElement1(list3);//getElement1(list4);//報錯 Object類型是Number的父類,需要Number子類//getElement2(list1);//報錯 Integer是Number的子類,需要Number的父類//getElement2(list2);//報錯 String和Number沒有關系getElement2(list3);getElement2(list4);System.out.println("----------------------------------");//Collection集合中的方法 boolean addAll(Collection<? extends E> c);ArrayList<Integer> list01 = new ArrayList<>();list01.add(1);list01.add(2);ArrayList<Object> list02 = new ArrayList<>();//addAll的限制,傳遞list01集合泛型只能使用list02集合泛型的子類或者本身list02.addAll(list01);//把list01集合中的所有元素都存儲到list02中System.out.println(list02);//[1, 2]ArrayList<String> list03 = new ArrayList<>();//list03.addAll(list01);}// 泛型的上限:此時的泛型?,必須是Number類型或者Number類型的子類public static void getElement1(Collection<? extends Number> coll){}// 泛型的下限:此時的泛型?,必須是Number類型或者Number類型的父類public static void getElement2(Collection<? super Number> coll){}}