Java基礎學習筆記(十六)—— Iterator的使用與java常用容器的遍歷方法
Life was like a box of chocolates, you never know what you’re gonna get.
| @Author:TTODS
目錄
Iterator接口提供的方法
hasNext()
如果迭代具有更多元素,則返回 true 。
next()
返回迭代中的下一個元素。
ArrayList<Integer> myArray = new ArrayList<>();
myArray.add(5);
myArray.add(4);
myArray.add(3);
myArray.add(2);
myArray.add(1);
Iterator<Integer> iter = myArray.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
/*
5
4
3
2
1
*/
remove()
從底層集合中刪除此迭代器返回的最後一個元素(可選操作)。
ArrayList<Integer> myArray = new ArrayList<>();
myArray.add(5);
myArray.add(4);
myArray.add(3);
myArray.add(2);
myArray.add(1);
Iterator<Integer> iter = myArray.iterator();
System.out.println(myArray);
while(iter.hasNext()) {
iter.next();
iter.remove();
}
System.out.println(myArray);
輸出:
[5, 4, 3, 2, 1]
[]
forEachRemaining(Consumer<? super E> action)
對每個剩餘元素執行給定的操作,直到所有元素都被處理或動作引發異常。
我們在java的官方文檔中找不到Iterator的具體實現類,因爲Iterator對象一般由容器類提供Iterator()方法返回來得到,可迭代的容器實現了接口Iterable,該接口要求子類實現Iterator()方法和forEach()方法。Iterator接口的實現一般在容器的內部進行。下面是ArrayList基於Iterator接口的實現類Itr的源碼
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
常見容器的遍歷
ArrayList與LinkedList
ArrayList與LinkedList的遍歷方法基本一樣,下面以ArrayList爲例
for語句
ArrayList<Integer> myArray = new ArrayList<>(Arrays.asList(5,4,3,2,1));
for(int index=0;index<myArray.size();index++)
System.out.println(myArray.get(index));
輸出
5
4
3
2
1
forEach語句
ArrayList<Integer> myArray = new ArrayList<>(Arrays.asList(5,4,3,2,1));
for(Integer num:myArray) {
System.out.println(num);
}
輸出
5
4
3
2
1
迭代器
ArrayList<Integer> myArray = new ArrayList<>(Arrays.asList(5,4,3,2,1));
Iterator<Integer> iter = myArray.iterator();
while(iter.hasNext())
System.out.println(iter.next());
輸出
5
4
3
2
1
Set集合
由於Set集合中的元素是無序的,所以我們不能使用for循環根據索引來遍歷Set集合
forEach語句
HashSet<String> myHashSet = new HashSet<>(Arrays.asList("one","two","three","four"));
for(String str:myHashSet) {
System.out.println(str);
}
輸出
four
one
two
three
迭代器
HashSet<String> myHashSet = new HashSet<>(Arrays.asList("one","two","three","four"));
Iterator<String> iter = myHashSet.iterator();
while(iter.hasNext())
System.out.println(iter.next());
}
輸出
four
one
two
three
Map
Map是由一個Key集合,和一個Value容器組成的,遍歷時可以單獨的遍歷Key集合,也可以單獨的遍歷Value容器,單獨遍歷的方法上面已經展示過了,下面代碼僅演示如何通過Key集合來遍歷Value容器
HashMap<Integer,Character> myHashMap = new HashMap<>();
myHashMap.put(1,'A');
myHashMap.put(2,'B');
myHashMap.put(3,'C');
myHashMap.put(4,'D');
myHashMap.put(5,null);
Set<Integer> keys = myHashMap.keySet();
for(Integer key:keys) {
System.out.println(key+"=>"+myHashMap.get(key));
}
輸出
1=>A
2=>B
3=>C
4=>D
5=>null