JavaEE学习之【迭代器、泛型】

来源:互联网 发布:java分布式框架 dubbo 编辑:程序博客网 时间:2024/05/17 01:24

迭代器(iterator

什么叫迭代:

Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。


主要方法:hasNext()和next()方法

1. hasNext()方法:用来判断集合中是否有下一个元素可以迭代。如果返回true,说明可以迭代。

2. next()方法:用来返回迭代的下一个元素,并把指针向后移动一位。

迭代的常规用法中我们要尽量避免在迭代过程中为集合添加/删除数据。否则会报错,原因是Java抛出了并发修改异常。

迭代器发生并发修改异常:

原因是:迭代器在迭代的时候,如果集合对元素进行了修改,迭代器预想的元素个数和实际元素的个数发生改变。

解决办法:1让集合自己遍历2通过迭代器子类Listiterator可以实现(迭代器类本身没有add方法)

1.Iterator迭代器概述




 

 泛型概述

泛型用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。

泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。

泛型的定义:定义泛型可以在类中预支地使用未知的类型。

泛型的使用:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。

 使用泛型的好处

将运行时期的ClassCastException,转移到了编译时期变成了编译失败。

l 避免了类型强转的麻烦。如果不使用过泛型集合得到的数据不知道集体类型,当我们遍历读取的时候就需要使用强转把他们转换成同一类型不然就会报错。

演示下列代码:(可以粘贴复制运行比较一下)

public class Test {

 

public static void main(String[]args) {

//method01();//这个方法是不使用泛型的方法

method02();

}

 

private static void method02() {

// 1.定义有泛型的ArrayList

Collection<String> list = new ArrayList<String>();

// 2.添加字符串

list.add("abc");

list.add("itcast");

// 3.添加Integer类型

// list.add(5); //当集合明确类型后,存放类型不一致就会编译报错

// 4.获取迭代器

Iterator<String> it = list.iterator();

// 5.判断是否有下一个元素

while (it.hasNext()) {

// 6.获取下一个元素,元素是String类型

String str = it.next();

// 7.获取字符串的长度

System.out.println(str.length());

}

}

 

private static void method01() {

// 1.定义没有泛型的ArrayList

Collection list =new ArrayList<String>();

// 2.添加字符串

list.add("abc");

list.add("itcast");

// 3.添加Integer类型

list.add(5);//没有泛型,任意类型都能放入

// 4.获取迭代器

Iterator it =list.iterator();

// 5.判断是否有下一个元素

while (it.hasNext()) {

// 6.获取下一个元素,并强转为String类型

String str = (String)it.next();

// 7.获取字符串的长度

System.out.println(str.length());

}

}

}

使用迭代器的好处:

集合明确具体存放的元素类型,那么在使用迭代器的时候,迭代器也同样会知道具体遍历元素类型,存放类型不一致就会编译报错,避免了类型强转的麻烦.

 

泛型的定义与使用

我们在集合中会大量使用到泛型,这里来完整地学习泛型知识。

泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。

含有泛型的类

定义格式:修饰符 class类名<代表泛型的变量> {  }

例如,API中的ArrayList集合:

class ArrayList<E>{

public boolean add(E e){ }

public Eget(int index){  }

}

 

使用格式:创建对象时,确定泛型的类型

例如,ArrayList<String> list = new ArrayList<String>();

此时,变量E的值就是String类型

class ArrayList<String>{

public boolean add(String e){ }

public Stringget(int index){  }

}

例如,ArrayList<Integer> list = new ArrayList<Integer>();

此时,变量E的值就是Integer类型

class ArrayList<Integer>{

public boolean add(Integer e){ }

public Integerget(int index){  }

}

举例自定义泛型类

publicclass GenericClass<E>{//自定义的类中,可以写<>泛型

   //E 表示未知的数据类型 调用者创建对象的时候,才能明确数据类型

private Ee;

publicvoid setE(E e){

this.e = e;

}

public E getE(){

returne;

}

}

使用:

publicclass GenericClassTest {

publicstaticvoid main(String[] args) {

//对自定义的泛型类,进行测试

GenericClass<Integer> g = new GenericClass<Integer>();

         //E传递什么类型就是什么类型

g.setE(100);

Integer i = g.getE();

System.out.println(i);

}

}

含有泛型的方法

定义格式:修饰符 <代表泛型的变量>返回值类型 方法名(参数){  }

例如,

publicclass GenericMethod <E>{

Public void show(E e){

System.out.println(e);

}

public<T>void function(T t){//自定义泛型的方法

//自己写一个方法,方法中的数据类型,采用<>泛型

    //如果方法中的泛型,和类上的泛型不同

// 在方法返回值前加入<>

System.out.println(t);

}

}

使用格式:调用方法时,确定泛型的类型

publicclass GenericMethodTest {

publicstaticvoid main(String[] args) {

GenericMethod<Double> g = new GenericMethod<Double>();

g.show(1.1);

g.function(1.2F);//传递什么类型就是什么类型

}

}

 含有泛型的接口

定义格式:修饰符 interface接口名<代表泛型的变量> {  }

n 例如,

publicinterface Inter <E>{

publicabstractvoid show(E e);

}

使用格式:

1、定义类时确定泛型的类型

n 例如

publicclass InterImplimplements Inter<Integer>{

publicvoid show(Integer i){

System.out.println(i);

}

}

此时,变量E的值就是Integer类型。

 

2、始终不确定泛型的类型,直到创建对象时,确定泛型的类型

n 例如

InterImpl<String> imp= new InterImpl<String>();

此时,变量E的值就是String类型。

publicclass InterImpl<E>implements Inter<E>{

publicvoid show(E e){

System.out.println(e);

}

}

 泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

定义:(查看ArrayList的构造方法)无法在类中使用

使用:调用方法时可以给予任意类型。参照Arraylist的构造方法

? extends E代表只要是E类型的子类即可

? super E代表只要是E类型的父类即可

 

/*

 * 泛型通配符?,代表任意的数据类型

 *

 * 定义:(查看ArrayList的构造方法)无法在类中使用

 *

 * 使用:调用方法时可以给予任意类型。参照Arraylist的构造方法

 * public ArrayList(Collection<? extends E> c)

 * 为了便于?的理解,我们将以上方法重写为public ArrayList(ArrayList<? extends E> c)

 *

 * 该方法的意思:创建集合对象A时,给于另外一个集合对象B作为参数,则创建好的集合A中包含了集合B中的元素

 *

 * ? extends E代表只要是E类型的子类即可

 * ? super E代表只要是E类型的父类即可

 */

publicclass Demo01 {

publicstaticvoid main(String[] args) {

//定义集合b,包含3个元素

ArrayList<String> listB = new ArrayList<String>();

listB.add("Jack");

listB.add("Rose");

listB.add("Trump");

//使用集合b创建集合a

ArrayList<Object> listA = new ArrayList<Object>(listB);

listA.add("Obama");

//观察集合A

System.out.println(listA);

}