Java 更高级的接口使用

Java 更高级的接口使用,java,interface,iterator,iteration,Java,Interface,Iterator,Iteration,老实说,我不太确定我自己是否理解这个任务:)有人告诉我创建类MySimpleIt,它实现迭代器和Iterable,并允许运行提供的测试代码。对象的参数和变量不能是集合或数组。 守则: MySimpleIt msi=new MySimple(10,100, MySimpleIt.PRIME_NUMBERS); for(int el: msi) System.out.print(el+" "); System.out.pri

老实说,我不太确定我自己是否理解这个任务:)有人告诉我创建类MySimpleIt,它实现迭代器和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循环中也有错误,因为编译器希望在那里使用“int”而不是“Object”。有人知道如何解决这个问题吗?

这个作业的设计有很多错误

使用
enum
测试代码包含以下代码段:

MySimpleIt(erator?).PRIME_NUMBERS
MySimpleIt(erator?).ODD_NUMBERS
MySimpleIt(erator?).EVEN_NUMBERS
一个地方的类型是
myimpleit
,另一个地方的类型是
myimpleiterator
。无论哪种方式,该名称都建议使用一个接口来定义一组常量。这不是正确使用
接口

更好的设计是使用
enum

enum SequenceType {
  PRIME_NUMBERS, ODD_NUMBERS, EVEN_NUMBERS;
}
请参阅:有效Java第二版第30项:使用枚举而不是
int
常量


考虑<代码>接口的多个实现,而不是使用代码> SETType 的整块 看起来你的定序器应该能够随心所欲地切换序列类型。这将导致该类成为一个巨大的blob,它必须知道如何生成每种类型的序列。它可能只适用于这里给出的3种类型,但如果您以后想添加更多类型的序列,它肯定是一个糟糕的设计

考虑对不同类型的序列使用相同接口的不同实现。您可能需要定义一个
AbstractIntegerSequencer
,它定义了基本功能(重置边界、回答
hasNext()
迭代器()
,等等),将子类委托给
抽象保护的int-generateNext()
。这样,将要生成的序列类型的细节很好地封装到每个子类中

您仍然可以使用
enum SequenceType
作为
static
factory方法,该方法实例化这些不同的子类,每个序列类型一个,但这些序列本身可能不能随心所欲地切换类型


使用泛型 不要让类型
实现迭代器
,而应该让它
实现迭代器

来自(他们的强调):

只允许使用原始类型作为对遗留代码兼容性的让步。强烈反对在Java编程语言中引入泛型之后编写的代码中使用原始类型Java编程语言的未来版本可能不允许使用原始类型

另请参见有效的Java第二版第32项:不要在新代码中使用原始类型


不要将
Iterator
Iterable
混淆。 假设你有这样的东西:

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实现Iterable,则Iterator
@Override Iterator Iterator()
返回该值,则第二个循环不会打印任何内容,因为
seq
是它自己的
iterator()
,并且在这一点上,对于
seq
没有更多的
hasNext()

Iterable
的正确实现应该能够为用户生成所需的任意多个独立的
迭代器
,并且这种实现将再次打印上述代码中
0
10
之间的素数


有关堆叠溢出的进一步资料
    • 关于
      PrimeGenerator实现迭代器的问题

这份作业的设计有很多错误

使用
enum
测试代码包含以下代码段:

MySimpleIt(erator?).PRIME_NUMBERS
MySimpleIt(erator?).ODD_NUMBERS
MySimpleIt(erator?).EVEN_NUMBERS
一个地方的类型是
myimpleit
,另一个地方的类型是
myimpleiterator
。无论哪种方式,该名称都建议使用一个接口来定义一组常量。这不是正确使用
接口

更好的设计是使用
enum

enum SequenceType {
  PRIME_NUMBERS, ODD_NUMBERS, EVEN_NUMBERS;
}
请参阅:有效Java第二版第30项:使用枚举而不是
int
常量


考虑<代码>接口的多个实现,而不是使用代码> SETType 的整块 看起来你的定序器应该能够随心所欲地切换序列类型。这将导致该类成为一个巨大的blob,它必须知道如何生成每种类型的序列。它可能只适用于这里给出的3种类型,但如果您以后想添加更多类型的序列,它肯定是一个糟糕的设计

考虑对不同类型的序列使用相同接口的不同实现。您可能需要定义一个
AbstractIntegerSequencer
,它定义了基本功能(重置边界、回答
hasNext()
迭代器()
,等等),将子类委托给
抽象保护的int-generateNext()
。这样,将要生成的序列类型的细节很好地封装到每个子类中

您仍然可以使用
enum SequenceType
作为
static
factory方法,该方法实例化这些不同的子类,每个序列类型一个,但这些序列本身可能不能随心所欲地切换类型


使用泛型 不要让类型
实现迭代器
,而应该让它
实现迭代器

来自(他们的强调):

只允许使用原始类型作为对遗留代码兼容性的让步。在以后编写的代码中使用原始类型