说实话我不太确定我是否自己理解这个任务:)我被告知创建类MySimpleIt,它实现Iterator和Iterable并允许运行提供的测试代码。对象的参数和变量不能是集合或数组 代码:
MySimpleIt msi=new MySimple(10,100,
MySimpleIt.PRIME_NUMBERS);
for(int el: msi)
System.out.print(el+" ");
System.out.println();
msi.setType(MySimpleIterator.ODD_NUMBERS);
msi.setLimits(15,30);
for(int el: msi)
System.out.print(el+" ");
System.out.println();
msi.setType(MySimpleIterator.EVEN_NUMBERS);
for(int el: msi)
System.out.print(el+" ");
System.out.println();
我应该获得的结果:
11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
15 17 19 21 23 25 27 29
16 18 20 22 24 26 28 30
这是我的代码:
import java.util.Iterator;
interface MySimpleIterator{
static int ODD_NUMBERS=0;
static int EVEN_NUMBERS = 1;
static int PRIME_NUMBERS = 2;
int setType(int i);
}
public class MySimpleIt implements Iterable, Iterator, MySimpleIterator {
public MySimple my;
public MySimpleIt(MySimple m){
my = m;
}
public int setType(int i){
my.numbers = i;
return my.numbers;
}
public void setLimits(int d, int u){
my.down = d;
my.up = u;
}
public Iterator iterator(){
Iterator it = this.iterator();
return it;
}
public void remove(){
}
public Object next(){
Object o = new Object();
return o;
}
public boolean hasNext(){
return true;
}
}
class MySimple {
public int down;
public int up;
public int numbers;
public MySimple(int d, int u, int n){
down = d;
up = u;
numbers = n;
}
}
在测试代码中,我在创建MySimpleIt msi对象时遇到错误,因为它找到MySimple而不是MySimpleIt。我在for-each循环中也有错误,因为编译器需要'ints'而不是Object。任何人都知道如何解决它?
答案 0 :(得分:6)
这项任务的设计存在很多错误。
enum
测试代码包含以下代码段:
MySimpleIt(erator?).PRIME_NUMBERS
MySimpleIt(erator?).ODD_NUMBERS
MySimpleIt(erator?).EVEN_NUMBERS
在一个地方,类型为MySimpleIt
,另一个地方为MySimpleIterator
。无论哪种方式,该名称建议使用接口来定义一堆常量。这不是interface
!!!
使用enum
代替更好的设计:
enum SequenceType {
PRIME_NUMBERS, ODD_NUMBERS, EVEN_NUMBERS;
}
请参阅: Effective Java 2nd Edition 项目30:使用枚举而不是int
常量。
interface
的多个实现,而不是setType
看起来您的音序器应该能够随心所欲地切换序列类型。这将导致该类成为一个巨大的blob,必须知道如何生成每种类型的序列。它可能只适用于这里给出的3种类型,但如果你以后想要添加更多类型的序列,它肯定是一个糟糕的设计。
考虑为不同类型的序列提供相同接口的不同实现。您可能希望定义一个AbstractIntegerSequencer
来定义基本功能(重置边界,回答hasNext()
,iterator()
等),委托给abstract protected int generateNext()
的子类到{{ 1}}。这样,生成的序列类型的细节很好地封装到每个子类。
您仍然可以@Override
保留enum SequenceType
工厂方法来实例化这些不同的子类,每个序列类型一个,但这些序列本身可能不应该随意切换类型。
您应该将其设为static
。
implements Iterator
来自JLS 4.8 Raw Types(强调他们的):
原始类型的使用仅允许作为遗留代码兼容性的让步。强烈建议不要在将通用性引入Java编程语言之后编写的代码中使用原始类型。 未来版本的Java编程语言可能会禁止使用原始类型。
另请参阅 Effective Java 2nd Edition 项目32:不要在新代码中使用原始类型。
implements Iterator<Integer>
与Iterator<T>
混淆。假设你有这样的事情:
Iterable<T>
如果您将IntegerSequencer seq = new PrimeSequencer(0, 10);
for (int i : seq) {
System.out.println(i);
} // prints "2", "3", "5", 7"
for (int i : seq) {
System.out.println(i);
} // what should it print???
和seq implements Iterable<Integer>, Iterator<Integer>
设为@Override Iterator<Integer> iterator()
,则第二个循环不会打印任何内容,因为return this;
是其自己的seq
,并且在那时,iterator()
不再有hasNext()
。
seq
的正确实施应该能够为用户生成尽可能多的独立Iterable<Integer>
,这样的实现将再次在Iterator<Integer>
和{{1}之间打印素数在上面的代码中。