Java 集合中關(guān)于Iterator和ListIterator的用法說明
1.Iterator
Iterator的定義如下:
public interface Iterator<E> {}
Iterator是一個接口,它是集合的迭代器。集合可以通過Iterator去遍歷集合中的元素。Iterator提供的API接口如下:

forEachRemaining(Consumer<? super E> action):為每個剩余元素執(zhí)行給定的操作,直到所有的元素都已經(jīng)被處理或行動將拋出一個異常
hasNext():如果迭代器中還有元素,則返回true。
next():返回迭代器中的下一個元素
remove():刪除迭代器新返回的元素。

例子:
import java.util.*;
public class TestIterator {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
a.add("aaa");
a.add("bbb");
a.add("ccc");
System.out.println("Before iterate : " + a);
Iterator<String> 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,然后進(jìn)行判斷刪除bbb,最后ArrayList里只剩 aaa,ccc。
我們來驗(yàn)證一下:

注意:
(1)Iterator只能單向移動。
(2)Iterator.remove()是唯一安全的方式來在迭代過程中修改集合;如果在迭代過程中以任何其它的方式修改了基本集合將會產(chǎn)生未知的行為。而且每調(diào)用一次next()方法,remove()方法只能被調(diào)用一次,如果違反這個規(guī)則將拋出一個異常。
2.ListIterator
ListIterator是一個功能更加強(qiáng)大的, 它繼承于Iterator接口,只能用于各種List類型的訪問。可以通過調(diào)用listIterator()方法產(chǎn)生一個指向List開始處的ListIterator, 還可以調(diào)用listIterator(n)方法創(chuàng)建一個一開始就指向列表索引為n的元素處的ListIterator。
我們先來看一段關(guān)于ListIterator的描述:

ListIterator接口定義如下:
Interface ListIterator<E>{}

包含的方法有:
由以上定義我們可以推出ListIterator可以:
(1)雙向移動(向前/向后遍歷).
(2)產(chǎn)生相對于迭代器在列表中指向的當(dāng)前位置的前一個和后一個元素的索引.
(3)可以使用set()方法替換它訪問過的最后一個元素.
(4)可以使用add()方法在next()方法返回的元素之前或previous()方法返回的元素之后插入一個元素.
使用例子:
import java.util.*;
public class TestListIterator{
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
a.add("aaa");
a.add("bbb");
a.add("ccc");
System.out.println("Before iterate : " + a);
ListIterator<String> it = a.listIterator()
while (it.hasNext()) {
System.out.println(it.next() + ", " + it.previousIndex() + ", " + it.nextIndex());
}
while (it.hasPrevious()) {
System.out.print(it.previous() + " ");
}
System.out.println();
it = a.listIterator(1);//調(diào)用listIterator(n)方法創(chuàng)建一個一開始就指向列表索引為n的元素處的ListIterator。
while (it.hasNext()) {
String t = it.next();
System.out.println(t);
if ("ccc".equals(t)) {
it.set("nnn");
} else {
it.add("kkk");
}
}
System.out.println("After iterate : " + a);
}
}
解釋:
第1行:新建一個ArrayList,命名為a;
第2行、第3行和第4行分別一次往ArrayList里添加了aaa,bbb,ccc;
第5行:輸出ArrayList里的值:aaa,bbb,ccc
第6行:調(diào)用了a的listIterator方法,并使ListIterator類型的it指向,也就是說ListIterator類型的it指向了ArrayList容器, 通過調(diào)用ArrayList的listIterator方法來進(jìn)行容器內(nèi)的遍歷。
第7行、8、9行,調(diào)用it的hasNext()方法進(jìn)行判斷容器中是否還有元素,如果有,則輸出元素,當(dāng)前元素前一個元素的索引,當(dāng)前元素后一個元素的索引,
所以會輸出:
aaa,0,1
bbb,1,2
ccc,2,3
第10行,此時,it已經(jīng)指向了ArrayList的最后一個元素,在這里調(diào)用了ListIterator的hasPrevious()方法,就是,開始往前遍歷(上面是往后遍歷) 在這個while循環(huán)中,會以此輸出:ccc bbb aaa。
第13行:輸出換行。
第14行:現(xiàn)在it應(yīng)該已經(jīng)再一次指向ArrayList的開頭。在這一行中,it又被用到了,同樣的用到了ArrayList的listIteror方法,這一次不同,而是it指向了listIteror的第二個元素,因?yàn)槭?,第一個元素的索引是0,也就是說it指向了ArrayList里的bbb。bbb是開頭的元素。
第15行:再一次是調(diào)用了ListIterator的hasnext()方法,來判斷ArrayList里是否還有元素。
第16行:調(diào)用了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?,F(xiàn)在容器中有aaa、bbb、kkk以及ccc。返回到第15行,再次以此往下執(zhí)行,會進(jìn)行if判斷,然后把ccc設(shè)置nnn。
第24行,最后輸出ArrayList里的元素:aaa、bbb、kkk、nnn。
我們來驗(yàn)證一下:

Iterator和ListIterator區(qū)別
我們在使用List,Set的時候,為了實(shí)現(xiàn)對其數(shù)據(jù)的遍歷,我們經(jīng)常使用到了Iterator(迭代器)。使用迭代器,你不需要干涉其遍歷的過程,只需要每次取出一個你想要的數(shù)據(jù)進(jìn)行處理就可以了。但是在使用的時候也是有不同的。List和Set都有iterator()來取得其迭代器。
對List來說,你也可以通過listIterator()取得其迭代器,兩種迭代器在有些時候是不能通用的,Iterator和ListIterator主要區(qū)別在以下方面:
(1)ListIterator有add()方法,可以向List中添加對象,而Iterator不能
(2)ListIterator和Iterator都有hasNext()和next()方法,可以實(shí)現(xiàn)順序向后遍歷,但是ListIterator有hasPrevious()和previous()方法,可以實(shí)現(xiàn)逆向(順序向前)遍歷。Iterator就不可以。
(3)ListIterator可以定位當(dāng)前的索引位置,nextIndex()和previousIndex()可以實(shí)現(xiàn)。Iterator沒有此功能。
(4)都可實(shí)現(xiàn)刪除對象,但是ListIterator可以實(shí)現(xiàn)對象的修改,set()方法可以實(shí)現(xiàn)。Iierator僅能遍歷,不能修改。
因?yàn)長istIterator的這些功能,可以實(shí)現(xiàn)對LinkedList等List數(shù)據(jù)結(jié)構(gòu)的操作。其實(shí),數(shù)組對象也可以用迭代器來實(shí)現(xiàn)。
以上這篇Java 集合中關(guān)于Iterator和ListIterator的用法說明就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
spring boot開發(fā)遇到坑之spring-boot-starter-web配置文件使用教程
Spring Boot支持容器的自動配置,默認(rèn)是Tomcat,當(dāng)然我們也是可以進(jìn)行修改的。這篇文章給大家介紹了spring boot開發(fā)遇到坑之spring-boot-starter-web配置文件使用教程,需要的朋友參考下吧2018-01-01
基于SpringBoot和PostGIS的某國基地可視化實(shí)戰(zhàn)
本文以Java開發(fā)語言為例,使用SpringBoot框架來進(jìn)行后臺開發(fā),詳細(xì)講解如何使用Leaflet對PostGIS的全球基地信息進(jìn)行Web可視化,最后分享Web可視化結(jié)果,感興趣的朋友跟隨小編一起看看吧2024-08-08
基于Java實(shí)現(xiàn)一個簡單的單詞本Android App的實(shí)踐
本文基于Java實(shí)現(xiàn)了一個簡單的單詞本安卓app,用的是SQLite數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
解析Spring Boot內(nèi)嵌tomcat關(guān)于getServletContext().getRealPath獲取得到臨時
大家都很糾結(jié)這個問題在使用getServletContext().getRealPath()得到的是臨時文件的路徑,每次重啟服務(wù),這個臨時文件的路徑還好變更,下面小編通過本文給大家分享Spring Boot內(nèi)嵌tomcat關(guān)于getServletContext().getRealPath獲取得到臨時路徑的問題,一起看看吧2021-05-05

