1.Iterator
Iterator的定義如下:
public interface Iterator<E> {}
Iterator是一個接口,它是集合的迭代器。集合可以通過Iterator去遍歷集合中的元素。Iterator提供的API接口如下:
-
forEachRemaining(Consumer<? super E> action):為每個剩余元素執行給定的操作,直到所有的元素都已經被處理或行動將拋出一個異常
-
hasNext():如果迭代器中還有元素,則返回true。
-
next():返回迭代器中的下一個元素
-
remove():從迭代器指向的collection中移除迭代器返回的最后一個元素(可選操作).。
注意:如果迭代刪除每一個元素,就必須使用迭代器方式進行刪除;,否則會出現ConcurrentModificationException - 并發修改異常
2.迭代器如何使用
2.1 迭代器正常遍歷集合
public class demo {public static void main(String[ ] args) {ArrayList<Integer> arr=new ArrayList<>();arr.add(10);arr.add(20);arr.add(30);arr.add(40);arr.add(50);Iterator<Integer> it=arr.iterator();while (it.hasNext()){system.out.print(it.next()+"");}}
}
結果:
10 20 30 40 50
2.2 完全版迭代器可以一邊遍歷一邊刪除元素
public class demo {public static void main(String[ ] args){ArrayList<Integer> arr=new ArrayList<>();arr.add(10);arr.add(20);arr.add(30);arr.add(40);arr.add(50);system.out.println("Before iterate : " +arr);Iterator<Integer> it=arr.iterator();while (it.hasNext()){System.out.print(it.next()+"");it.remove();}system.out.println();//換行system.out.println(arr);}
}
結果如下:
Before iterate :[10,20,30,40,50]
10 20 30 40 50
[]
注意:
(1)Iterator只能單向移動。
(2)Iterator.remove()是唯一安全的方式來在迭代過程中修改集合;如果在迭代過程中以任何其它的方式修改了基本集合將會產生未知的行為。而且每調用一次next()方法,remove()方法只能被調用一次,如果違反這個規則將拋出一個異常。
2.3 foreach循環刪除元素則會報錯
public class demo {public static void main(String[] args) {ArrayList<Integer> arr=new ArrayList<>();arr.add(10);arr.add(20);arr.add(30);arr.add(40);arr.add(50);for (Integer integer : arr) {system.out.print(integer);arr.remove(integer);}}
}
for-each循環不支持集合在迭代過程中的結構性修改(如添加或刪除元素)
使用迭代器(Iterator
)顯式地刪除元素:
Iterator<Integer> iterator = arr.iterator(); ?
while (iterator.hasNext()) { ?iterator.next(); // 移動到下一個元素 ?iterator.remove(); // 刪除當前元素 ?
}
在普通for循環,remove(int index)
方法可以刪除元素,但是索引值會改變。
for (int i = arr.size() - 1; i >= 0; i--) { ?arr.remove(i); ?
}
總結:
????????迭代器僅僅是遍歷輸出語句!本身并沒有任何排序等其他功能,在數據結構的二叉樹中別認為迭代器輸出二叉樹是因為迭代器會排序,是因為排序二叉樹本身有序,迭代器僅僅是按照排序二叉樹本身的排序規則輸出罷了。
3. ListIterator
ListIterator是一個功能更加強大的, 它繼承于Iterator接口,只能用于各種List類型的訪問---專門為 List
集合設計。
可以通過調用 listIterator() 方法產生一個指向List開始處的ListIterator, 還可以調用listIterator(n)方法創建一個一開始就指向列表索引為n的元素處的ListIterator。
我們先來看一段關于ListIterator的描述:
ListIterator接口定義如下:
Interface ListIterator<E>{}
包含的方法有:
ListIterator
的主要方法包括:
-
boolean hasNext()
: 檢查列表中是否還有下一個元素。 -
E next()
: 返回列表中的下一個元素,并將迭代器位置向前移動一位。 -
boolean hasPrevious()
: 檢查列表中是否還有上一個元素。 -
E previous()
: 返回列表中的上一個元素,并將迭代器位置向后移動一位。 -
int nextIndex()
: 返回對下一個元素的索引(正向迭代中的索引)。 -
int previousIndex()
: 返回對上一個元素的索引(反向迭代中的索引)。 -
void add(E e)
: 在迭代器的當前位置插入指定的元素(可選操作)。 -
void set(E e)
: 用指定的元素替換迭代器最后返回的元素(可選操作)。 -
void remove()
: 從列表中移除迭代器最后返回的元素(可選操作)。
由以上定義我們可以推出ListIterator可以:
(1)雙向移動(向前/向后遍歷)。
(2)產生相對于迭代器在列表中指向的當前位置的前一個或后一個元素的索引。
(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() + " ");//ccc bbb aaa}System.out.println();it = a.listIterator(1);//調用listIterator(n)方法創建一個一開始就指向列表索引為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);}
}
Before iterate : [aaa, bbb,ccc]
aaa,0,1
bbb,1,2
ccc,2,3
ccc bbb aaa
bbb
ccc
After iterate : [aaa,bbb,kkk, nnn]
Iterator和ListIterator區別 我們在使用List,Set的時候,為了實現對其數據的遍歷,我們經常使用到了Iterator(迭代器)。使用迭代器,你不需要干涉其遍歷的過程,只需要每次取出一個你想要的數據進行處理就可以了。但是在使用的時候也是有不同的。List和Set都有iterator()來取得其迭代器。對List來說,你也可以通過listIterator()取得其迭代器,兩種迭代器在有些時候是不能通用的,Iterator和ListIterator主要區別在以下方面:
-
ListIterator有add()方法,可以向List中添加對象,而Iterator不能
-
ListIterator和Iterator都有hasNext()和next()方法,可以實現順序向后遍歷,但是ListIterator有hasPrevious()和previous()方法,可以實現逆向(順序向前)遍歷。Iterator就不可以。
-
ListIterator可以定位當前的索引位置,nextIndex()和previousIndex()可以實現。Iterator沒有此功能。
-
都可實現刪除對象,但是ListIterator可以實現對象的修改,set()方法可以實現。Iierator僅能遍歷,不能修改。
因為ListIterator的這些功能,可以實現對LinkedList等List數據結構的操作。其實,數組對象也可以用迭代器來實現。