samwellwang

samwellwang

coder
twitter

Java 迭代器(Iterator 和 ListIterator)

今天查资料的时候看到一个迭代器的东西,不晓得干嘛的。进而学习一下

2019-04-02

今天查资料的时候看到一个迭代器的东西,不晓得干嘛的。进而学习一下

Iterator#

Iterator 的定义如下:
publicinterface Iterator {}
Iterator 是一个接口,它是集合的迭代器。集合可以通过 Iterator 去遍历集合中的元素。Iterator 提供的 API 接口如下:

forEachRemaining (Consumer action):为每个剩余元素执行给定的操作,直到所有的元素都已经被处理或行动将抛出一个异常
hasNext ():如果迭代器中还有元素,则返回 true。
next ():返回迭代器中的下一个元素
remove ():删除迭代器新返回的元素。

例子:
import java.util.*;
publicclassTestIterator{
publicstaticvoidmain(String[] args){
        ArrayList a = new ArrayList();
        a.add("aaa");
        a.add("bbb");
        a.add("ccc");
        System.out.println("Before iterate : " + a);
        Iterator it = a.iterator();
while (it.hasNext()) {
            String t = it.next();
if ("bbb".equals(t)) {
                it.remove();
            }
        }
        System.out.println("After iterate : " + a);
    }
}

我们可以看到:首先往一个 ArrayList 里装了 aaa,bbb,ccc,然后进行判断删除 bbb,最后 ArrayList 里只剩 aaa,ccc。
我们来验证一下:

注意:
(1)Iterator 只能单向移动。
(2)Iterator.remove () 是唯一安全的方式来在迭代过程中修改集合;如果在迭代过程中以任何其它的方式修改了基本集合将会产生未知的行为。而且每调用一次 next () 方法,remove () 方法只能被调用一次,如果违反这个规则将抛出一个异常。

ListIterator#

ListIterator 是一个功能更加强大的,它继承于 Iterator 接口,只能用于各种 List 类型的访问。可以通过调用 listIterator () 方法产生一个指向 List 开始处的 ListIterator, 还可以调用 listIterator (n) 方法创建一个一开始就指向列表索引为 n 的元素处的 ListIterator。
我们先来看一段关于 ListIterator 的描述:

ListIterator 接口定义如下:

Interface ListIterator{}

包含的方法有:


由以上定义我们可以推出 ListIterator 可以:
(1) 双向移动(向前 / 向后遍历).
(2) 产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引.
(3) 可以使用 set () 方法替换它访问过的最后一个元素.
(4) 可以使用 add () 方法在 next () 方法返回的元素之前或 previous () 方法返回的元素之后插入一个元素.
使用例子:

import java.util.*;
publicclassTestListIterator{
publicstaticvoidmain(String[] args){
1       ArrayList a = new ArrayList();
2       a.add("aaa");
3       a.add("bbb");
4       a.add("ccc");
5       System.out.println("Before iterate : " + a);
6       ListIterator it = a.listIterator()
7while (it.hasNext()) {
8           System.out.println(it.next() + ", " + it.previousIndex() + ", " + it.nextIndex());
9       }
10while (it.hasPrevious()) {
11            System.out.print(it.previous() + " ");
12        }
13        System.out.println();
14        it = a.listIterator(1);//调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator。
15while (it.hasNext()) {
16            String t = it.next();
17            System.out.println(t);
18if ("ccc".equals(t)) {
19                it.set("nnn");
20            } else {
21                it.add("kkk");
22            }
23        }
24        System.out.println("After iterate : " + a);
    }
}


解释:
第 1 行:新建一个 ArrayList,命名为 a;
第 2 行、第 3 行和第 4 行分别一次往 ArrayList 里添加了 aaa,bbb,ccc;
第 5 行:输出 ArrayList 里的值:aaa,bbb,ccc
第 6 行:调用了 a 的 listIterator 方法,并使 ListIterator 类型的 it 指向,也就是说 ListIterator 类型的 it 指向了 ArrayList 容器, 通过调用 ArrayList 的 listIterator 方法来进行容器内的遍历。
第 7 行、8、9 行,调用 it 的 hasNext () 方法进行判断容器中是否还有元素,如果有,则输出元素,当前元素前一个元素的索引,当前元素后一个元素的索引,
所以会输出:
aaa,0,1
bbb,1,2
ccc,2,3
第 10 行,此时,it 已经指向了 ArrayList 的最后一个元素,在这里调用了 ListIterator 的 hasPrevious () 方法,就是,开始往前遍历 (上面是往后遍历) 在这个 while 循环中,会以此输出: ccc bbb aaa。
第 13 行:输出换行。
第 14 行:现在 it 应该已经再一次指向 ArrayList 的开头。在这一行中,it 又被用到了,同样的用到了 ArrayList 的 listIteror 方法,这一次不同,而是 it 指向了 listIteror 的第二个元素,因为是 1,第一个元素的索引是 0,也就是说 it 指向了 ArrayList 里的 bbb。bbb 是开头的元素。
第 15 行:再一次是调用了 ListIterator 的 hasnext () 方法,来判断 ArrayList 里是否还有元素。
第 16 行:调用了 it 的 next () 方法,所谓 next 方法,是指找到剩下元素的第一个元素,也就是 bbb,并把它赋值了 String 的 t;
第 17 行:输出 bbb
第 18 行:19、20,21 行,如果 bbb 与 ccc 相等则将 bbb set 成 nnn,否则,add()来添加 kkk,那么在哪里添加呢,是在 next 方法返回的元素之前,next 方法返回的元素是 ccc,也就是在 bbb,和 ccc 之间添加 kkk。现在容器中有 aaa、bbb、kkk 以及 ccc。返回到第 15 行,再次以此往下执行,会进行 if 判断,然后把 ccc 设置 nnn。
第 24 行,最后输出 ArrayList 里的元素:aaa、bbb、kkk、nnn。

Iterator 和 ListIterator 区别#

我们在使用 List,Set 的时候,为了实现对其数据的遍历,我们经常使用到了 Iterator (迭代器)。使用迭代器,你不需要干涉其遍历的过程,只需要每次取出一个你想要的数据进行处理就可以了。但是在使用的时候也是有不同的。List 和 Set 都有 iterator () 来取得其迭代器。对 List 来说,你也可以通过 listIterator () 取得其迭代器,两种迭代器在有些时候是不能通用的,Iterator 和 ListIterator 主要区别在以下方面:
(1)ListIterator 有 add () 方法,可以向 List 中添加对象,而 Iterator 不能
(2)ListIterator 和 Iterator 都有 hasNext () 和 next () 方法,可以实现顺序向后遍历,但是 ListIterator 有 hasPrevious () 和 previous () 方法,可以实现逆向(顺序向前)遍历。Iterator 就不可以。
(3)ListIterator 可以定位当前的索引位置,nextIndex () 和 previousIndex () 可以实现。Iterator 没有此功能。
(4)都可实现删除对象,但是 ListIterator 可以实现对象的修改,set () 方法可以实现。Iierator 仅能遍历,不能修改。
因为 ListIterator 的这些功能,可以实现对 LinkedList 等 List 数据结构的操作。其实,数组对象也可以用迭代器来实现。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。