java.util.Collection介面 是集合的最頂層的介面,定義了集合共性的方法 介面無法直接創建對象,使用多態的方式創建對象 Collection<集合中的數據類型(泛型)> coll = new ArrayList<集合中的數據類型(泛型)>(); 迭代器 集合中存儲數據的方式(數據類型 ...
java.util.Collection介面
是集合的最頂層的介面,定義了集合共性的方法
介面無法直接創建對象,使用多態的方式創建對象
Collection<集合中的數據類型(泛型)> coll = new ArrayList<集合中的數據類型(泛型)>();
迭代器
集合中存儲數據的方式(數據類型)不一樣,取出集合中元素的方式也不同,java給我們提供了一種公共的取出元素的方式,叫迭代器
描述迭代器的介面:java.util.Iterator
介面中的抽象方法:
boolean hasNext() 如果仍有元素可以迭代,則返回 true。 判斷集合中還有沒有元素,有返回true,沒有返回false
E next() 返回迭代的下一個元素。 取出集合中的下一個元素
迭代器是一個介面,需要找到迭代器的實現類,迭代器的實現類是每個集合的內部類
在Collection介面中有一個方法: iterator方法返回的就是迭代器
Iterator<E> iterator() 返回在此 collection 的元素上進行迭代的迭代器。
ArrayList集合實現了Collection介面,重寫iterator方法,方法的返回值就是迭代器的實現類對象
註意:我們只需要知道iterator方法返回的而是迭代器的實現類就行了,不需要關註返回的是哪個實現類對象,這種變成方式叫做面向介面編程
迭代器的使用步驟:
1.創建集合對象,往集合中添加元素
2.使用集合中的方法iterator獲取迭代器的實現類對象,使用Iterator介面接收(多態)
3.使用iterator中的方法hasNext和next方法進行迭代,取出集合中的元素
1 public static void main(String[] args) { 2 //1.創建集合對象,往集合中添加元素 3 //Collection<String> coll = new ArrayList<String>(); 4 Collection<String> coll = new HashSet<String>(); 5 coll.add("姚明"); 6 coll.add("喬丹"); 7 coll.add("詹姆斯"); 8 coll.add("科比"); 9 coll.add("艾弗森"); 10 //2.使用集合中的方法iterator獲取迭代器的實現類對象,使用Iterator介面接收(多態) 11 //集合中的數據類型是什麼,迭代器的數據類型就是什麼,跟著集合走 12 Iterator<String> it = coll.iterator(); 13 //3.使用iterator中的方法hasNext和next方法進行迭代,取出集合中的元素 14 //boolean hasNext() 如果仍有元素可以迭代,則返回 true。 15 /*boolean b = it.hasNext(); 16 System.out.println(b); 17 //E(String) next() 返回迭代的下一個元素。 18 String s = it.next(); 19 System.out.println(s); 20 21 b = it.hasNext(); 22 System.out.println(b); 23 s = it.next(); 24 System.out.println(s); 25 26 b = it.hasNext(); 27 System.out.println(b); 28 s = it.next(); 29 System.out.println(s); 30 31 b = it.hasNext(); 32 System.out.println(b); 33 s = it.next(); 34 System.out.println(s); 35 36 b = it.hasNext(); 37 System.out.println(b); 38 s = it.next(); 39 System.out.println(s); 40 41 b = it.hasNext(); 42 System.out.println(b);//false,沒有元素了 43 s = it.next();//沒有元素了,在取就報NoSuchElementException沒有元素異常 44 System.out.println(s);*/ 45 46 /* 47 * 發現以上迭代的過程是一個重覆的過程,可以使用迴圈優化 48 * 我們不知道集合中有多少元素,所以可以使用while迴圈 49 * while迴圈的結束條件:hasNext();返回false 50 */ 51 while(it.hasNext()){ 52 String s = it.next(); 53 System.out.println(s); 54 } 55 System.out.println("-------------------"); 56 /* 57 * for迴圈方式迭代器,使用不多 58 */ 59 /*for(Iterator<String> it2 = coll.iterator();it2.hasNext();){ 60 String s = it2.next();//取出元素,移動指針到下一位 61 System.out.println(s); 62 }*/ 63 }
併發修改異常
在迭代的過程中,對集合的長度進行了修改,就會發生併發修改異常
遍歷的過程中,集合的長度進行了修改,但是迭代器並不知道,就會產生ConcurrentModificationException
解決方法:
1.迭代就是迭代,不要對集合進行修改
2.使用迭代器Iterator的子介面ListIterator中的方法add/remove,讓迭代器自己增加往集合中增加元素/移除元素
這樣迭代器本身知道了集合的變化,就不會產生併發修改異常了
void add(E e) 將指定的元素插入列表(可選操作)。
void remove() 從列表中移除由 next 或 previous 返回的最後一個元素(可選操作)。
1 public static void main(String[] args) { 2 ArrayList<String> list = new ArrayList<String>(); 3 4 list.add(null); 5 list.add("abc1"); 6 list.add("abc2"); 7 list.add("abc3"); 8 list.add("abc4"); 9 10 /* 11 * 使用迭代器遍歷集合 12 */ 13 //獲取迭代器 14 Iterator<String> it = list.iterator(); 15 //使用while遍歷集合 16 while(it.hasNext()){ 17 String s = it.next(); 18 19 /* 20 * 判斷集合中有沒有"abc3"這個元素 21 * 如果有,增加一個元素"itcast" 22 * 編程技巧:使用equals判斷的時候,要把已知的變數寫在前邊,未知的寫在後邊,防止空指針異常 23 */ 24 //if(s.equals("abc3")){ 25 if("abc3".equals(s)){ 26 //1.迭代就是迭代,不要對集合進行修改 27 //list.add("itcast"); 28 } 29 30 System.out.println(s); 31 } 32 33 System.out.println("------------------"); 34 35 /* 36 * 2.使用迭代器Iterator的子介面ListIterator中的方法add/remove,讓迭代器自己增加往集合中增加元素/移除元素 37 */ 38 ListIterator<String> listIt = list.listIterator(); 39 while(listIt.hasNext()){ 40 String s = listIt.next(); 41 if("abc3".equals(s)){ 42 listIt.add("itcast"); 43 } 44 System.out.println(s); 45 } 46 System.out.println(list); 47 }
增強for
內部是一個迭代器,簡化了迭代的代碼,使遍歷更加簡單
Collection介面繼承Iterable,所以Collection介面的所有實現類都可以是用增強for
註意:增強for是JDK1.5之後出現的
格式:
for(數據類型(集合/數組的數據類型) 變數名 : 集合名/數組名){
syso(變數名);
}
Java中的泛型
就是數據類型,在創建對象的時候確定
Java中的泛型是一個偽泛型:在編譯的時候有(寫代碼.java中),運行的時候(.class)沒有
隨機數:偽隨機數
泛型的好處:
1.避免強轉,可以直接使用元素特有的方法
2.把運行期的異常,轉換編譯期異常(編譯失敗)
定義含有泛型的類
模仿ArrayList集合
public class ArrayList<E>{}
E:是一個未知的數據類型,可能是Integer,可能是String,可能Person
創建類對象的時候確定數據類型
定義格式:
修飾符 class 類名<E>{
}
1 public class GenericClass<E> { 2 private E name; 3 4 public E getName() { 5 return name; 6 } 7 8 public void setName(E name) { 9 this.name = name; 10 } 11 12 public void method(E e){ 13 System.out.println(e); 14 }
定義含有泛型的介面
格式:
修飾符 interface 介面名<泛型>{
抽象方法(參數<泛型>);
}
1 public interface GenericInterface<E> { 2 public abstract void method(E e); 3 }
1 /* 2 * 1.定義介面的實現類,不管泛型,介面泛型是怎麼寫的,實現類也怎麼寫 3 * public class ArrayList<E> implements List<E>{} 4 * 創建實現類對象的時候確定泛型的數據類型 5 */ 6 class GenericInterfaceImpl1<E> implements GenericInterface<E>{ 7 8 @Override 9 public void method(E e) { 10 System.out.println(e); 11 } 12 }
含有泛型的方法
不是類上定義的泛型,是方法自己定義的泛型
定義格式:在修飾符和返回值類型之間要定義泛型,才能使用
修飾符 <泛型> 返回值類型 方法名(參數<泛型>){
}
方法上的泛型,在調用方法的時候確定數據類型,傳遞的是什麼類型的數據,泛型就是什麼類型(和類上的泛型沒有關係)
1 public class GenericMethod<E> { 2 3 /* 4 * 定義方法,使用類上的泛型 5 */ 6 public void method(E e){ 7 System.out.println(e); 8 } 9 10 /* 11 * 定義一個含有泛型的方法 12 */ 13 public <T> void function(T t){ 14 System.out.println(t); 15 }
泛型的通配符:?,代表任意的數據類型
上限限定:? extends E代表只要是E類型的子類即可
下限限定:? super E代表只要是E類型的父類即可
ArrayList集合的構造方法
ArrayList(Collection<? extends E> c)
參數是一個集合,集合的數據類型有要求,只能是ArrayList泛型的子類或者是本身
ArrayList(Collection<? extends E> c)
參數是一個集合,集合的數據類型有要求,只能是ArrayList泛型的子類或者是本身
1 /* 2 * 鬥地主案例: 3 * 1.準備牌 4 * 2.洗牌 5 * 3.發牌 6 * 4.看牌 7 */ 8 public class DouDiZhu { 9 public static void main(String[] args) { 10 //1.準備牌 11 //創建存儲54張牌的集合 12 ArrayList<String> poker = new ArrayList<String>(); 13 //存儲大王小王 14 poker.add("大王"); 15 poker.add("小王"); 16 //存儲52張牌 17 //創建序號的數組 18 String[] numbers = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"}; 19 //創建花色數組 20 String[] colors = {"?","?","?","?"}; 21 //嵌套遍歷兩個數組 22 for (String number : numbers) { 23 for (String color : colors) { 24 //System.out.println(color+number); 25 //把組合的牌放入到集合中 26 poker.add(color+number); 27 } 28 } 29 //System.out.println(poker); 30 31 /* 32 * 2.洗牌 33 * 使用Collections中的方法 34 * static void shuffle(List<?> list) 35 */ 36 Collections.shuffle(poker); 37 //System.out.println(poker); 38 39 /* 40 * 3.發牌 41 * 創建4個集合 42 * 遍歷poker集合 43 * 使用poker集合的索引%3發牌 44 */ 45 ArrayList<String> player01 = new ArrayList<String>(); 46 ArrayList<String> player02 = new ArrayList<String>(); 47 ArrayList<String> player03 = new ArrayList<String>(); 48 ArrayList<String> diPai = new ArrayList<String>(); 49 //遍歷poker集合 50 for (int i = 0; i < poker.size(); i++) { 51 //獲取牌 52 String s = poker.get(i); 53 //先判斷索引是否為底牌的索引 51 52 53 54 if(i >=51){ 55 //給底牌發牌 56 diPai.add(s); 57 }else if(i%3==0){ 58 //給玩家1發牌 59 player01.add(s); 60 }else if(i%3==1){ 61 //給玩家1發牌 62 player02.add(s); 63 }else if(i%3==2){ 64 //給玩家1發牌 65 player03.add(s); 66 } 67 } 68 //4.看牌 69 System.out.println("劉德華:"+player01); 70 System.out.println("周潤發:"+player02); 71 System.out.println("周星馳:"+player03); 72 System.out.println("底牌:"+diPai); 73 } 74 }