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]

  

posted @ 2019-12-09 17:01  绮丽梦境  阅读(409)  评论(0编辑  收藏  举报