16

我正在尝试了解 JavaIteratorIterable接口

我正在写这堂课

class MyClass implements Iterable<String> {
    public String[] a = null;
    public MyClass(String[] arr) {
        a = arr;    
    }

    public MyClassIterator iterator() {
        return new MyClassIterator(this);
    }

    public class MyClassIterator implements Iterator<String> {
        private MyClass myclass = null;
        private int count = 0;
        public MyClassIterator(MyClass m) {
            myclass = m;    
        }

        public boolean hasNext() {
            return count < myclass.a.length;
        }
        public String next() {
            int t = count;
            count++;
            return myclass.a[t];
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    }   
}

它似乎正在工作。

我应该有:

Myclass implements Iterable<Stirng>, Iterator<String> {

}

或者我应该放在MyClassIterator外面MyClass

class MyClass implements Iterable<String> {
    public String[] a = null;
    public MyClass(String[] arr) {
        a = arr;    
    }
    public MyClassIterator iterator() {
        return new MyClassIterator(this);
    }
}


    public class MyClassIterator implements Iterator<String> {
        private MyClass myclass = null;
        private int count = 0;
        public MyClassIterator(MyClass m) {
            myclass = m;    
        }

        public boolean hasNext() {
            return count < myclass.a.length;
        }
        public String next() {
            int t = count;
            count++;
            return myclass.a[t];
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    }   

哪一个更好?

4

3 回答 3

35

您几乎应该在同一个类中同时Iterable实现两者。Iterator他们做不同的事情。迭代器自然是有状态的——当您使用它进行迭代时,它必须更新其对世界的看法。然而,一个可迭代对象只需要能够创建新的迭代器。特别是,您可以让多个迭代器同时处理同一个原始可迭代对象。

您当前的方法非常好 - 我会更改实施的某些方面,但就职责分离而言很好。

于 2011-04-29T19:00:10.387 回答
9

你的第一次尝试走上了正轨。MyClass只需要实现Iterable<String>,这反过来又需要你提供一个Iterator<String>实现来返回Iterable<String>.iterator()

没有必要放在MyClassIterator外面,MyClass因为在大多数情况下,您甚至不需要直接使用(它被 s上的语法Iterator<String>隐式使用),并且在所有其他情况下,接口就足够了,除非您实际上向实现添加额外的行为(您可能永远不需要这样做)。for .. in ..Iterable<String>

这是我的做法,请参阅内联评论:

import java.util.Iterator;

class MyClass implements Iterable<String>{
    public String[] a=null; //make this final if you can
    public MyClass(String[] arr){
        a=arr; //maybe you should copy this array, for fear of external modification
    }

    //the interface is sufficient here, the outside world doesn't need to know
    //about your concrete implementation.
    public Iterator<String> iterator(){
        //no point implementing a whole class for something only used once
        return new Iterator<String>() {
            private int count=0;
            //no need to have constructor which takes MyClass, (non-static) inner class has access to instance members
            public boolean hasNext(){
                //simplify
                return count < a.length;
            }
            public String next(){
                return a[count++]; //getting clever
            }

            public void remove(){
                throw new UnsupportedOperationException();
            }
        };
    }
}
于 2011-04-29T19:29:57.993 回答
2

您不应该这样做,Myclass implements Iterable<String>,Iterator<String>{因为迭代器是一次性使用的。除了列表迭代器之外,没有办法将它们返回到开头。

顺便说一句,您可以跳过

MyClass myClass;
public MyClassInterator(MyClass m){
  myclass=m;  
}

而不是引用

myClass

参考

MyClass.this

您的内部类不是静态的,因此MyClass.this将引用创建它的封闭类的实例。

于 2011-04-29T19:01:30.620 回答