我正在嘗試爲我創建的集合編寫自定義迭代器。我對Interface Iterable的合同有點困惑。它有三個方法:next(),hasNext()和remove()。我的集合是不可變的,所以我打算爲remove()方法拋出一個UnsupportedOperationException。它也被稱爲「懶惰生成」,即元素不存儲在內存中,而是在需要時創建,但這不是在這裏或那裏。自定義寫入的迭代器爲每個循環都會拋出異常
的Iterator的next()方法的Javadoc如下:
E next()
Returns the next element in the iteration.
Returns:
the next element in the iteration
Throws:
NoSuchElementException - if the iteration has no more elements
和hasNext()是:
boolean hasNext()
Returns true if the iteration has more elements. (In other words, returns
true if next() would return an element rather than throwing an exception.)
這些規則去,我開始實施我的Set和Iterator ,得到這個:
import java.util.AbstractSet;
import java.util.Iterator;
public class PrimesBelow extends AbstractSet<Integer>{
int max;
int size;
public PrimesBelow(int max) {
this.max = max;
}
@Override
public Iterator<Integer> iterator() {
return new SetIterator<Integer>(this);
}
@Override
public int size() {
if(this.size == -1){
System.out.println("Calculating size");
size = calculateSize();
}else{
System.out.println("Accessing calculated size");
}
return size;
}
private int calculateSize() {
int c = 0;
for(Integer p: this)
c++;
return c;
}
public static void main(String[] args){
PrimesBelow primesBelow10 = new PrimesBelow(10);
for(int i: primesBelow10)
System.out.println(i);
System.out.println(primesBelow10);
}
}
。
import java.util.Iterator;
import java.util.NoSuchElementException;
public class SetIterator<T> implements Iterator<Integer> {
int max;
int current;
public SetIterator(PrimesBelow pb) {
this.max= pb.max;
current = 1;
}
@Override
public boolean hasNext() {
if(current < max) return true;
else return false;
}
@Override
public Integer next() {
while(hasNext()){
current++;
if(isPrime(current)){
System.out.println("returning "+current);
return current;
}
}
throw new NoSuchElementException();
}
private boolean isPrime(int a) {
if(a<2) return false;
for(int i = 2; i < a; i++) if((a%i)==0) return false;
return true;
}
}
這似乎罰款由我,下一個()返回下一個值,當沒有更多拋出異常。如果有更多的值要迭代,hasNext()應該返回true,否則返回false。然而,主循環的輸出是這樣的:
returning 2
2
returning 3
3
returning 5
5
returning 7
7
Exception in thread "main" java.util.NoSuchElementException
at SetIterator.next(SetIterator.java:27)
at SetIterator.next(SetIterator.java:1)
at PrimesBelow.main(PrimesBelow.java:38)
所以看起來在每個循環中都沒有處理異常。如何編寫一個我可以使用的自定義迭代器,以便它可以工作?我試圖返回null而不是拋出一個異常,但這只是一個NullPointerException。
我應該在Iterator完成時返回null,還是拋出Exception? Javadoc說next()應該拋出一個異常,但是當我將鼠標懸停在Eclipse的overriden方法next()上時,簽名不會顯示拋出NoSuchElementException,所以我對合同的內容非常困惑。我完成後返回null看起來很奇怪,因爲集合可能包含空元素。
感謝您的幫助。
爲什麼你在'next()'的實現中循環'hasNext()'?您應該只檢查是否有沒有while循環的下一個元素。 – dpr
我想我是這麼做的,因爲這是邏輯檢查Iterator是否可以返回更多元素的地方,以避免代碼重複並在if(current
user1661303
@ user1661303邏輯沒有意義,next()應該返回一個值(不循環)。而且這段代碼總是會拋出一個異常,因爲在遍歷所有元素之後,最終拋出一個異常無論如何都是 – nafas