java
想要遍歷Collection集合,那麼就要獲取該集合迭代器完成迭代操做,下面介紹一下獲取迭代器的方法【Collection接口中有一個方法】:數組
1 public Iterator iterator(): 獲取集合對應的迭代器,用來遍歷集合中的元素的。
ide
學習
public E next()
:返回迭代的下一個元素。優化
public boolean hasNext()
:若是仍有元素能夠迭代,則返回 true。this
使用步驟:
1.使用集合中的方法iterator()獲取迭代器的實現類對象,使用Iterator接口接收(多態)spa
Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什麼泛型,迭代器就是什麼泛型設計
2.使用Iterator接口中的方法hasNext判斷還有沒有下一個元素code
3.使用Iterator接口中的方法next取出集合中的下一個元素對象
1 import java.util.ArrayList; 2 import java.util.Collection; 3 import java.util.Iterator; 4 5 public class Demo01Iterator { 6 public static void main(String[] args) { 7 //建立一個集合對象 8 Collection<String> coll = new ArrayList<>(); 9 //往集合中添加元素 10 coll.add("姚明"); 11 coll.add("科比"); 12 coll.add("麥迪"); 13 coll.add("詹姆斯"); 14 coll.add("艾弗森"); 15 16 /* 17 1.使用集合中的方法iterator()獲取迭代器的實現類對象,使用Iterator接口接收(多態) 18 注意: 19 Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什麼泛型,迭代器就是什麼泛型 20 */ 21 //多態 接口 實現類對象 22 Iterator<String> it = coll.iterator(); 23 24 25 /* 26 發現使用迭代器取出集合中元素的代碼,是一個重複的過程 27 因此咱們可使用循環優化 28 不知道集合中有多少元素,使用while循環 29 循環結束的條件,hasNext方法返回false 30 */ 31 while(it.hasNext()){ 32 String e = it.next(); 33 System.out.println(e); 34 } 35 36 37 38 // 下面的代碼是一個一個在判斷取。 39 // 若是判斷爲false任然使用next方法取拋出NoSuchElementException異常 40 41 /* //2.使用Iterator接口中的方法hasNext判斷還有沒有下一個元素 42 boolean b = it.hasNext(); 43 System.out.println(b);//true 44 //3.使用Iterator接口中的方法next取出集合中的下一個元素 45 String s = it.next(); 46 System.out.println(s);//姚明 47 48 b = it.hasNext(); 49 System.out.println(b); 50 s = it.next(); 51 System.out.println(s); 52 53 b = it.hasNext(); 54 System.out.println(b); 55 s = it.next(); 56 System.out.println(s); 57 58 b = it.hasNext(); 59 System.out.println(b); 60 s = it.next(); 61 System.out.println(s); 62 63 b = it.hasNext(); 64 System.out.println(b); 65 s = it.next(); 66 System.out.println(s); 67 68 b = it.hasNext(); 69 System.out.println(b);//沒有元素,返回false 70 s = it.next();//沒有元素,在取出元素會拋出NoSuchElementException沒有元素異常 71 System.out.println(s);*/ 72 } 73 } 74
在調用Iterator的next方法以前,迭代器的索引位於第一個元素以前,不指向任何元素,當第一次調用迭代器的next方法後,迭代器的索引會向後移動一位,指向第一個元素並將該元素返回,當再次調用next方法時,迭代器的索引會指向第二個元素並將該元素返回,依此類推,直到hasNext方法返回false,表示到達了集合的末尾,終止對元素的遍歷。
原理圖:
Collection<E>extends Iterable<E>:全部的單列集合均可以使用加強for
public interface Iterable<T>:實現這個接口容許對象成爲 "foreach" 語句的目標。
語法:
1 for(元素的數據類型 變量 : Collection集合or數組){ 2 //寫操做代碼 3 }
1 import java.util.ArrayList; 2 3 public class Demo02Foreach { 4 public static void main(String[] args) { 5 demo02(); 6 } 7 8 //使用加強for循環遍歷集合 9 private static void demo02() { 10 ArrayList<String> list = new ArrayList<>(); 11 list.add("aaa"); 12 list.add("bbb"); 13 list.add("ccc"); 14 list.add("ddd"); 15 for(String s : list){ 16 System.out.println(s); 17 } 18 } 19 20 //使用加強for循環遍歷數組 21 private static void demo01() { 22 int[] arr = {1,2,3,4,5}; 23 for(int i:arr){ 24 System.out.println(i); 25 } 26 } 27 }
在前面學習集合時,咱們都知道集合中是能夠存聽任意對象的,只要把對象存儲集合後,那麼這時他們都會被提高成Object類型。當咱們在取出每個對象,而且進行相應的操做,這時必須採用類型轉換。
1 public class GenericDemo { 2 public static void main(String[] args) { 3 Collection coll = new ArrayList(); 4 coll.add("abc"); 5 coll.add("itcast"); 6 coll.add(5);//因爲集合沒有作任何限定,任何類型均可以給其中存放 7 Iterator it = coll.iterator(); 8 while(it.hasNext()){ 9 //須要打印每一個字符串的長度,就要把迭代出來的對象轉成String類型 10 String str = (String) it.next(); 11 System.out.println(str.length()); 12 } 13 } 14 }
上面的
好處:
1.避免了類型轉換的麻煩,存儲的是什麼類型,取出的就是什麼類型
2.把運行期異常(代碼運行以後會拋出的異常),提高到了編譯期(寫代碼的時候會報錯)
弊端:
泛型是什麼類型,只能存儲什麼類型的數據。
1 修飾符 class 類名<表明泛型的變量> { }
注意:泛型是數據類型的一部分,咱們將類名與泛型合併一塊兒看作數據類型。
泛型是一個未知的數據類型,當咱們不肯定使用什麼數據類型的時候,可使用泛型。泛型能夠接收任意的數據類型,可使用Integer,String,Student...
建立對象的時候肯定泛型的數據類型。
語法:
1 ArrayList<String> list = new ArrayList<String>();
這時在類定義時候的表明泛型的變量將會被String所代替。
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 13 14 ---------------------------------------------- 15 public class Demo02GenericClass { 16 public static void main(String[] args) { 17 18 //不寫泛型默認爲Object類型 19 GenericClass gc = new GenericClass(); 20 gc.setName("只能是字符串"); 21 Object obj = gc.getName();// 只能是字符串 22 23 24 //建立GenericClass對象,泛型使用Integer類型 25 GenericClass<Integer> gc2 = new GenericClass<>(); 26 gc2.setName(1); 27 Integer name = gc2.getName(); 28 System.out.println(name);// 1 29 30 31 //建立GenericClass對象,泛型使用String類型 32 GenericClass<String> gc3 = new GenericClass<>(); 33 gc3.setName("小明"); 34 String name1 = gc3.getName(); 35 System.out.println(name1);// 小明 36 } 37 }
語法:
定義含有泛型的方法:泛型定義在方法的修飾符和返回值類型之間
1 修飾符 <泛型> 返回值類型(能夠爲任意類型,也能夠爲泛型) 方法名(參數列表(使用泛型)){ 2 方法體; 3 }
含有泛型的方法,在調用方法的時候肯定泛型的數據類型。傳遞什麼類型的參數,泛型就是什麼類型
和普通方法使用同樣。當有返回值爲泛型的使用。那麼傳遞的是什麼類型的參數,就要用什麼什麼類型接收。
1 public class GenericMethod { 2 //定義一個含有泛型的方法。而且返回的也是泛型 3 public <M> M method01(M m){ 4 System.out.println(m); 5 return m; 6 } 7 8 9 // 定義一個含有泛型的方法。 10 public <M> void method02 (M m){ 11 System.out.println(m); 12 return m; 13 } 14 15 16 //定義一個含有泛型的靜態方法 17 public static <S> void method03 (S s){ 18 System.out.println(s); 19 } 20 } 21 22 23 ------------------------------------------------------------------ 24 public class Demo03GenericMethod { 25 public static void main(String[] args) { 26 //建立GenericMethod對象 27 GenericMethod gm = new GenericMethod(); 28 29 /* 30 調用含有泛型的方法method01 31 傳遞什麼類型,泛型就是什麼類型 32 */ 33 int a = gm.method01(10); 34 System.out.println("a:"+a); 35 36 String b = gm.method01("abc"); 37 System.out.println("b:"+b); 38 39 40 System.out.println("=============="); 41 gm.method02(8.8); 42 gm.method02(true); 43 44 45 System.out.println("=============="); 46 gm.method02("靜態方法,不建議建立對象使用"); 47 48 //靜態方法,經過類名.方法名(參數)能夠直接使用 49 GenericMethod.method03("靜態方法"); 50 GenericMethod.method03(1); 51 } 52 }
1 修飾符 interface接口名<表明泛型的變量> { 2 // 方法 3 }
第一種使用方式:定義接口的實現類,實現接口,指定接口的泛型。
源碼中的使用:Scanner類實現了Iterator接口,並指定接口的泛型爲String,因此重寫的next方法泛型默認就是String
1 public final class Scanner implements Iterator<String>{ 2 public String next() {} 3 }
1 public interface GenericInterface<I> { 2 public abstract void method(I i); 3 4 public abstract I get(); 5 } 6 7 8 --------------------------------------------------- 9 public class GenericInterfaceImpl1 implements GenericInterface<String>{ 10 @Override 11 public void method(String s) { 12 System.out.println(s); 13 } 14 15 @Override 16 public String get() { 17 return null; 18 } 19 } 20 21 22 ------------------------------------------------------------------------------ 23 public class Demo04GenericInterface { 24 public static void main(String[] args) { 25 //建立GenericInterfaceImpl1對象 26 GenericInterfaceImpl1 gi1 = new GenericInterfaceImpl1(); 27 // 只能傳遞字符串 28 gi1.method("字符串"); 29 30 } 31 }
第二種使用方式:接口使用什麼泛型,實現類就使用什麼泛型,類跟着接口走。就至關於定義了一個含有泛型的類,建立對象的時候肯定泛型的類型。
1 public interface List<E>{ 2 boolean add(E e); 3 E get(int index); 4 } 5 6 7 public class ArrayList<E> implements List<E>{ 8 public boolean add(E e) {} 9 public E get(int index) {} 10 }
1 public interface GenericInterface<I> { 2 public abstract void method(I i); 3 4 public abstract I get(); 5 } 6 7 8 ------------------------------------------------------ 9 public class GenericInterfaceImpl2<I> implements GenericInterface<I> { 10 @Override 11 public void method(I i) { 12 System.out.println(i); 13 } 14 15 @Override 16 public I get() { 17 return null; 18 } 19 } 20 21 22 --------------------------------------------------------------------------- 23 public class Demo04GenericInterface { 24 public static void main(String[] args) { 25 26 //建立GenericInterfaceImpl2對象 27 GenericInterfaceImpl2<Integer> gi2 = new GenericInterfaceImpl2<>(); 28 // 建立的對象爲何類型就能夠傳遞什麼類型 29 gi2.method(10); 30 31 GenericInterfaceImpl2<Double> gi3 = new GenericInterfaceImpl2<>(); 32 gi3.method(8.8); 33 } 34 }
?:表明任意的數據類型
使用方式:
不能建立對象使用
只能做爲方法的參數使用
1 import java.util.ArrayList; 2 import java.util.Iterator; 3 4 public class Demo05Generic { 5 public static void main(String[] args) { 6 ArrayList<Integer> list01 = new ArrayList<>(); 7 list01.add(1); 8 list01.add(2); 9 10 ArrayList<String> list02 = new ArrayList<>(); 11 list02.add("a"); 12 list02.add("b"); 13 14 printArray(list01); 15 printArray(list02); 16 17 // 不能建立對象使用 18 //ArrayList<?> list03 = new ArrayList<?>(); 19 } 20 21 /* 22 定義一個方法,能遍歷全部類型的ArrayList集合 23 這時候咱們不知道ArrayList集合使用什麼數據類型,能夠泛型的通配符?來接收數據類型 24 注意: 25 泛型沒有繼承概念的 26 */ 27 public static void printArray(ArrayList<?> list){ 28 //使用迭代器遍歷集合 29 Iterator<?> it = list.iterator(); 30 31 while(it.hasNext()){ 32 //it.next()方法,取出的元素是Object,能夠接收任意的數據類型 33 Object o = it.next(); 34 System.out.println(o); 35 } 36 37 } 38 }
泛型的上限限定: ? extends E 表明使用的泛型只能是E類型的子類/自己
泛型的下限限定: ? super E 表明使用的泛型只能是E類型的父類/自己
1 import java.util.ArrayList; 2 import java.util.Collection; 3 4 /* 5 泛型的上限限定: ? extends E 表明使用的泛型只能是E類型的子類/自己 6 泛型的下限限定: ? super E 表明使用的泛型只能是E類型的父類/自己 7 */ 8 public class Demo06Generic { 9 public static void main(String[] args) { 10 11 /* 12 類與類之間的繼承關係 13 Integer extends Number extends Object 14 String extends Object 15 */ 16 Collection<Integer> list1 = new ArrayList<Integer>(); 17 Collection<String> list2 = new ArrayList<String>(); 18 Collection<Number> list3 = new ArrayList<Number>(); 19 Collection<Object> list4 = new ArrayList<Object>(); 20 21 getElement1(list1); 22 //getElement1(list2);//報錯 23 getElement1(list3); 24 //getElement1(list4);//報錯 25 26 //getElement2(list1);//報錯 27 //getElement2(list2);//報錯 28 getElement2(list3); 29 getElement2(list4); 30 } 31 32 // 泛型的上限:此時的泛型?,必須是Number類型或者Number類型的子類 33 public static void getElement1(Collection<? extends Number> coll){} 34 // 泛型的下限:此時的泛型?,必須是Number類型或者Number類型的父類 35 public static void getElement2(Collection<? super Number> coll){} 36 37 }
--------------------