我的学习之路_第六章_迭代器,泛型
【Collection】 类
接口类
所属包:java.util.Collection
Collection类是集合的最顶层的接口,定义了集合共性的方法.
接口无法创建对象,使用多态的方式创建对象
Collection<集合中的数据类型(泛型)> 变量名 = new ArrayList<集合中的数据类型(泛型)>();
Collection接口常用子类接口有: List接口 set接口
List接口常用子类有: ArrayList类 LinkedList类
set接口常用的子类有: HashSet类 LinkenHashSet类
Collection类中的方式:
返回值:boolean add(E e) 往集合中添加元素
返回值:boolean remover(Object o) 删除集合中某一个元素
返回值:boolean contins(Object o) 判断对象是否存在于集合中
返回值:int size() 返回此集合中的元素数
返回值:Objec[] toArray() 把集合转成数组
没有返回值 clear() 移除此colection中的所有元素
【迭代器】
迭代器:是集合中存储数据的方式(数据类型)不一样,取出集合中元素的方式也不同,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方法进行迭代,取出集合中的元素
并发修改异常:
在迭代的过程中,对集合的长度进行了修改,就会发生并发修改异常.
遍历的过程中,集合的长度进行了修改,但是迭代器并不知道,就会产生ConcurrentModificationException
解决方法:
1:迭代就是迭代,不要对集合进行修改
2:使用迭代器 Iterator 的子接口 ListIterator 中的方法add/remove,让迭代器自己往集合中增加/移除元素
这样迭代器本身知道了集合的变化,就不会发生并发修改异常了.
没有返回值 add(E e)将制定的元素插入列表
没有返回值 remove() 从列表中移除有next 或 previous 返回的最后一个元素
【增强for】:
内部是一个迭代器,简化了迭代的代码,使遍历更加简单
Collection接口继承了Iterable,所以Collection接口的所有实现类都是可以使用增强for
注意:增强for是JDK1.5版本以后出现的
格式: for(数据类型(集合/数组的数据类型) 变量名: 集合名/数组名){
}
好处:简化了遍历的代码
弊端:没有了索引,不能对集合进行增删
【泛型】
泛型就是数据类型,在创建对象的时候确定
java中的泛型都是伪泛型:在编译(.java文件中有)的时候有,运行(.class文件中没有)的时候没有
泛型的好处:
1:避免强转,可以直接使用元素特有的方法
2:把运行期的异常,转换成编译期异常(编译失败)
定义含有泛型的类:
模仿ArrayList集合
修饰符 class 类名 <E>{ }
定义含有泛型的接口:
格式: 修饰符 interface 接口名<泛型>{
抽象方法(参数<泛型>);
}
E:是一个位置的数据类型 可能任何引用数据类型
创建对象的时候确定数据类型
定义接口的实现类,不管泛型,接口泛型是怎么写的,实现类也怎么写
public class ArrayList<E> implements List<E>{}
创建实现类对象的时候确定泛型的数据类型
【含有泛型的方法】:不是类上定义的泛型,是方法自己定义的泛型
定义格式: 在修饰符和返回值类型之间要定义泛型,才能使用
修饰符<泛型> 返回值类型 方法名(参数<泛型>){ }
方法上的泛型,在调用方法的时候确定数据类型,传递的是什么类型的数据,泛型就是什么类型(和类上的泛型没有关系)
【泛型的通配符】
? 代表任意的数据类型
在定义遍历集合的方法时可以使用 因为要遍历的集合类型可能不一样,传递一个 通配符 ? 就可以一个方法,重复使用来遍历不同类型的集合.
泛型的限定:(了解,能看懂java的底层源码即可)
上限限定: ? extends E 代表只要是E类型的子类即可
下限限定: ? super E 代表只要是E类型的父类即可