Java集合-Iterator
點擊關(guān)注,與你共同成長!

Java集合-Iterator
Java Iterator接口表示一個對象,該對象能夠遍歷Java對象的集合,一次迭代一個對象。Iterator 接口是Java中用于迭代對象集合的最古老的機制之一(盡管不是最早的-Enumerator 早于Iterator )。
使用java的Iterator ,首先從需要迭代的對象集合中獲取一個Iterator 實例。獲得的迭代器跟蹤底層集合中的元素,以確保遍歷所有元素。如果在遍歷指向該集合的迭代器時,修改基礎(chǔ)集合,迭代器通常會檢測到它,并在下次嘗試從迭代器獲取下一個元素時拋出異常。下面會繼續(xù)講述。
Iterator核心方法
Iterator接口非常簡單,下面是核心方法:
方法 | 說明 |
hasNext() | 如果Iterator還有元素則返回true,否則返回false |
next() | 返回Iterator的下一個元素 |
remove() | 從Iterator代的集合中移除next()返回的最新元素。 |
forEachRemaining() | 迭代Iterator中所有剩余的元素,并調(diào)用一個Lambda表達式,將剩余的每個元素作為參數(shù)傳遞給Lambda表達式。 |
獲取Iterator
通常情況下,將通過從包含多個嵌套對象的Java對象獲取迭代器來與它交互。標準的java集合接口Collection 包含一個iterator()方法,調(diào)用iterator()方法可以從Collection中獲取一個迭代器。可以從java集合各個數(shù)據(jù)結(jié)構(gòu)中獲取Iterator 例如, List, Set, Map, Queue, Deque或者 Map。下面是從各個集合中獲取Iterator 的例子:
List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
Iterator<String> iterator = list.iterator();
Set<String> set = new HashSet<>();
set.add("one");
set.add("two");
set.add("three");
Iterator<String> iterator2 = set.iterator();
迭代Iterator
可以用while 循環(huán)迭代Iterator ,下面是例子:
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
Object nextObject = iterator.next();
}
上面的例子使用了Iterator 的兩個方法,第一個 hasNext(),如果Iterator 還有元素則返回true。換句話說,如果迭代器還沒有遍歷從中獲取迭代器的集合中的所有元素,hasNext()方法將返回true。如果迭代器迭代了底層集合中的所有元素,hasNext()方法返回false。
第二個方法是next(),next()返回Iterator 的下一個元素。
迭代順序
Iterator的順序取決于迭代的集合,例如從List中獲取的Iterator ,則元素的存儲順序與List中的元素引用,另一方面,從Set中獲得的迭代器并不保證集合中元素的精確迭代順序。
List的Iterator
下面是從List 實例中獲取Iterator :
List list = new ArrayList();
list.add("123");
list.add("456");
list.add("789");
Iterator iterator = list.iterator();
Set的Iterator
下面是從Set中獲取Iterator 實例:
Set set = new HashSet();
set.add("123");
set.add("456");
set.add("789");
Iterator iterator = set.iterator();
迭代時修改集合
有些集合使用Iterator 迭代時不允許修改集合,否則在迭代器下一次調(diào)用next()方法時,會拋ConcurrentModificationException ,下面是例子:
package cn.com.codingce.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorTest {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("123");
list.add("456");
list.add("789");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
String value = iterator.next();
if(value.equals("456")){
list.add("999");
}
}
}
}
執(zhí)行結(jié)果:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.ck.collection.IteratorTest.main(IteratorTest.java:19)
如果通過Iterator迭代集合的同時修改了集合,則會引發(fā)ConcurrentModificationException,因為迭代器與集合不同步。
迭代時移除元素
Java迭代器接口有一個remove()方法,可以從底層集合中移除next()剛剛返回的元素,調(diào)用remove()方法不會拋ConcurrentModificationException 異常,下面是代碼:
List<String> list = new ArrayList<>();
list.add("123");
list.add("456");
list.add("789");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
String value = iterator.next();
if(value.equals("456")){
iterator.remove();
}
}
forEachRemaining()
forEachRemaining()方法,可以迭代Iterator內(nèi)部剩余的元素,對于每個元素,調(diào)用作為參數(shù)傳遞給forEachRemaining()的Lambda表達式,下面是代碼:
List<String> list = new ArrayList<>();
list.add("Jane");
list.add("Heidi");
list.add("Hannah");
Iterator<String> iterator = list.iterator();
iterator.forEachRemaining((element) -> {
System.out.println(element);
});
ListIterator
Java 還有一個接口ListIterator繼承了Iterator接口,ListIterator接口,它表示一個雙向迭代器,意味著可以向前和向后迭代元素的迭代器。
這兒不詳細講解,用一個例子說明怎么使用:
List<String> list = new ArrayList<>();
list.add("Jane");
list.add("Heidi");
list.add("Hannah");
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()) {
System.out.println(listIterator.next());
}
while(listIterator.hasPrevious()) {
System.out.println(listIterator.previous());
}
上面可以看到,第一個例子ListIterator向后迭代,第二個例子向前迭代。
實現(xiàn)Iterator接口
如果有一個特殊的、定制的集合類型,那么可以自己實現(xiàn)Iterator接口來創(chuàng)建一個迭代器,該迭代器可以遍歷自定義集合的元素。在本節(jié)中,將展示一個超簡單的Java迭代器接口的定制實現(xiàn),將了解實現(xiàn)迭代器接口的外觀。將為其實現(xiàn)迭代器的集合是一個標準的List,它不是一個完全完美的實現(xiàn),因為它不能在迭代期間檢測到列表內(nèi)容的更改,但是它足以讓您了解迭代器實現(xiàn)的外觀,下面是代碼:
import java.util.Iterator;
import java.util.List;
public class ListIterator <T> implements Iterator<T> {
private List<T> source = null;
private int index = 0;
public ListIterator(List<T> source){
this.source = source;
}
@Override
public boolean hasNext() {
return this.index < this.source.size();
}
@Override
public T next() {
return this.source.get(this.index++);
}
}
下面是一個在上面的ListIterator的迭代過程中它的外觀的示例:
import java.util.ArrayList;
import java.util.List;
public class ListIteratorExample {
public static void main(String[] args) {
List<String> list = new ArrayList();
list.add("one");
list.add("two");
list.add("three");
ListIterator<String> iterator = new ListIterator<>(list);
while(iterator.hasNext()) {
System.out.println( iterator.next() );
}
}
}

以上,便是今天的分享,希望大家喜歡,覺得內(nèi)容不錯的,歡迎「分享」「贊」或者點擊「在看」支持,謝謝各位。
