gpt4 book ai didi

java - 自定义编写的 Set 迭代器在 for-each 循环中抛出异常

转载 作者:行者123 更新时间:2023-11-30 02:25:19 30 4
gpt4 key购买 nike

我正在尝试为我制作的 Set 编写一个定制的迭代器。我对可迭代接口(interface)的契约有点困惑。它具有三个方法:next()、hasNext() 和remove()。我的集合是不可变的,所以我计划为方法remove()抛出一个UnsupportedOperationException。它也被称为“延迟生成”,即元素不存储在内存中,而是在需要时创建,但这既不存在也不存在。

迭代器的 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;
}
}

这对我来说似乎很好,next() 返回下一个值并在没有更多值时抛出异常。如果有更多值需要迭代,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)

所以看来异常没有在 foreach 循环中处理。如何编写一个可以使用的自定义迭代器才能使其正常工作?我尝试返回 null 而不是抛出异常,但这只是给出了 NullPointerException。

当迭代器完成时我应该返回 null,还是抛出异常?Javadoc 说 next() 应该抛出异常,但是当我将鼠标悬停在 Eclipse 中的重写方法 next() 上时,签名没有显示抛出 NoSuchElementException,所以我对契约(Contract)所说的内容感到非常困惑。对我来说,完成后返回 null 似乎很奇怪,因为集合可能包含 null 元素。

感谢您的帮助。

最佳答案

改变

while(hasNext()) {
//...
}
throw new NoSuchElementException();

if(hasNext()) {
//...
} else {
throw new NoSuchElementException();
}

关于java - 自定义编写的 Set 迭代器在 for-each 循环中抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45756368/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com