更高级的接口用法

owc*_*wca 0 java iteration iterator interface

说实话,我不太确定自己是否理解这个任务:)我被告知创建类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();
Run Code Online (Sandbox Code Playgroud)

我应该得到的结果:

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
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在测试代​​码中,我在创建MySimpleIt msi对象时遇到错误,因为它找到MySimple而不是MySimpleIt.我在for-each循环中也有错误,因为编译器需要'ints'而不是Object.任何人都知道如何解决它?

pol*_*nts 6

这项任务的设计有很多错误.

使用 enum

测试代码包含以下代码段:

MySimpleIt(erator?).PRIME_NUMBERS
MySimpleIt(erator?).ODD_NUMBERS
MySimpleIt(erator?).EVEN_NUMBERS
Run Code Online (Sandbox Code Playgroud)

在一个地方,类型是MySimpleIt,在另一个地方MySimpleIterator.无论哪种方式,该名称建议使用接口来定义一堆常量.这不是一个正确的使用interface!!!

使用一个更好的设计enum:

enum SequenceType {
  PRIME_NUMBERS, ODD_NUMBERS, EVEN_NUMBERS;
}
Run Code Online (Sandbox Code Playgroud)

请参阅:Effective Java 2nd Edition项目30:使用枚举而不是int常量.


考虑多个实现interface而不是monolithsetType

看起来您的音序器应该能够随心所欲地切换序列类型.这将导致该类成为一个巨大的blob,必须知道如何生成每种类型的序列.它可能只适用于这里给出的3种类型,但如果你以后想要添加更多类型的序列,它肯定是一个糟糕的设计.

考虑为不同类型的序列提供相同接口的不同实现.您可能需要定义一个AbstractIntegerSequencer定义的基本功能(重置界限,回答hasNext(),iterator()等),委托给一个abstract protected int generateNext()子类要@Override.这样,生成的序列类型的细节很好地封装到每个子类.

您仍然可以保留enum SequenceType一个static工厂方法来实例化这些不同的子类,每个序列类型一个,但这些序列本身可能不应该随心所欲地切换类型.


使用泛型

而不是制作你的类型implements Iterator,你应该做到implements Iterator<Integer>.

来自JLS 4.8原始类型(强调他们的):

原始类型的使用仅允许作为遗留代码兼容性的让步.强烈建议不要在将通用性引入Java编程语言之后编写的代码中使用原始类型.未来版本的Java编程语言可能会禁止使用原始类型.

另请参阅Effective Java 2nd Edition项目32:不要在新代码中使用原始类型.


不要混淆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???
Run Code Online (Sandbox Code Playgroud)

如果您seq implements Iterable<Integer>, Iterator<Integer>@Override Iterator<Integer> iterator()return this;,那么第二个循环将不显示任何信息,因为seq是自己的iterator(),而在这一点上没有更多hasNext()seq.

适当的实现Iterable<Integer>应该能够为用户生成尽可能多的独立Iterator<Integer>,并且这种实现将再次在上述代码之间0和之中打印素数10.


有关stackoverflow的进一步读数