我注意到有位在下列情況下一個奇怪的行爲:的Java 8迭代開始流入到迭代導致hasNext()冗餘呼叫
迭代器 - >流 - >地圖() - >中的iterator() - >迭代
原始迭代器的hasNext()在已經返回false後被稱爲額外時間。
這是正常的嗎?
package com.test.iterators;
import java.util.Iterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class TestIterator {
private static int counter = 2;
public static void main(String[] args) {
class AdapterIterator implements Iterator<Integer> {
boolean active = true;
@Override
public boolean hasNext() {
System.out.println("hasNext() called");
if (!active) {
System.out.println("Ignoring duplicate call to hasNext!!!!");
return false;
}
boolean hasNext = counter >= 0;
System.out.println("actually has next:" + active);
if (!hasNext) {
active = false;
}
return hasNext;
}
@Override
public Integer next() {
System.out.println("next() called");
return counter--;
}
}
Stream<Integer> stream = StreamSupport.stream(Spliterators.spliteratorUnknownSize(new AdapterIterator(), 0), false);
stream.map(num -> num + 1).iterator().forEachRemaining(num -> {
System.out.println(num);
});
}
}
如果我或者刪除地圖()或()像數或收集(更換最終itearator()),它的工作原理沒有冗餘呼叫。
輸出
hasNext() called
actually has next:true
next() called
3
hasNext() called
actually has next:true
next() called
2
hasNext() called
actually has next:true
next() called
1
hasNext() called
actually has next:true
hasNext() called
Ignoring duplicate call to hasNext!!!!
我不會稱之爲「正常」,但在規範內。 – Holger 2015-03-13 17:48:43
你的意思是因爲Iterator.hasNext()必須是冪等的,對吧? – 2015-03-13 21:59:32
對,可能會像調用者喜歡的那樣頻繁地調用下一個... – Holger 2015-03-16 08:41:06