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 }
--------------------