Iterator迭代器
1.Iterator接口
public interface Iterator<E>
对 collection 进行迭代的迭代器。
Java中有多种集合,不同集合存储元素的方式不尽相同。
Iterator提供了一种对于不同集合的通用遍历方式。
集合的顶层接口Collection中有一个方法iterator(),返回值是带有泛型的Iterator接口类型
当Collection的实现类如ArrayList去调用该方法时,返回的就是ArrayList的迭代器对象;
HashSet去调用该方法时,返回的就是HashSet的迭代器对象。
如此一来,我们不必关注集合的数据结构(用迭代器去遍历)
也不必关心集合对应的迭代器对象具体是什么(用Iterator这个父类接口引用指向子类的实现类对象,多态)
就可以对集合进行遍历
2.Iterator迭代器原理
Iterator内部有一个指针,通过调用迭代器的hasNext()方法判断是否有下一个元素,如果有,则调用next()方法返回该元素并将指针向后移动一位。
Iterator只能是从头开始,单向遍历
例子:
public static void main(String[] args){ //创建List集合 List<String> list = new ArrayList<String>(); //给集合中添加元素 list.add("111"); list.add("222"); list.add("333"); list.add("444"); Iterator<String> it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } }
输出:
111 222 333 444
3.Iterator的并发修改异常
Iterator迭代器遍历过程中,集合的长度不能通过集合的add()或remove()方法发生变化,否则就会发生 java.util.ConcurrentModificationException(并发修改异常)
(通过集合的set()方法修改元素是没问题的,因为集合长度没有变化)
public static void main(String[] args){ List<String> list = new ArrayList<String>(); list.add("111"); list.add("222"); list.add("333"); list.add("444"); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()) { String str = iterator.next(); if(str.equals("222")) { //list.add("AAA");//错误,不能通过集合方法改变集合长度 list.set(0, "KKK");//可以通过集合的set方法修改 } System.out.println(str); } System.out.println(list); }
输出:
111
222
333
444
[KKK, 222, 333, 444]
要想在遍历过程中改变集合长度,只有通过迭代器的remove()方法。可以移除迭代器返回的最后一个元素。
public static void main(String[] args){ List<String> list = new ArrayList<String>(); list.add("111"); list.add("222"); list.add("333"); list.add("444"); Iterator<String> iterator = list.iterator(); while(iterator.hasNext()) { String str = iterator.next(); if(str.equals("222")) { iterator.remove(); } System.out.println(str); } System.out.println(list); }
输出:
111
222
333
444
[111, 333, 444]
除此之外,不能有其他方法改变数组长度。
关于remove()方法的使用,有两点需要注意:
remove()方法只能在next()方法之后调用;
调用一次next()方法后,只能调用一次remove();
4.ListIterator
ListIterator是Iterator的子接口,Iterator有的功能它都有。只能用于List接口的迭代
系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。ListIterator 没有当前元素;它的光标位置 始终位于调用 previous() 所返回的元素和调用 next() 所返回的元素之间。
ListIterator的功能:
可以通过调用listIterator(n)方法,生成迭代器的时候指定开始遍历的光标
可以从前往后遍历,也可以从后往前遍历
可以使用add()方法在迭代过程中增加元素(该元素直接插入到 next 返回的下一个元素的前面(如果有),或者 previous 返回的下一个元素之后(如果有);简单来说这个新增加的元素就是下一个要遍历的元素)
可以使用set()方法修改元素(注意这个set()是迭代器的方法)
public static void main(String[] args){ //创建List集合 List<String> list = new ArrayList<String>(); //给集合中添加元素 list.add("111"); list.add("222"); list.add("333"); list.add("444"); ListIterator<String> it = list.listIterator(4); while(it.hasPrevious()) { String s = it.previous(); System.out.println(s); if(s.equals("222")) { it.add("AAA"); } } System.out.println("========"); System.out.println(list); }
输出:
444 333 222 AAA 111 ======== [111, AAA, 222, 333, 444]