在同一个类中实现多个迭代器

时间:2014-01-19 22:33:06

标签: java iterator override

我正在回顾一下我写的一些代码,我需要不同的迭代器,我注意到我正常编写第一个迭代器,就像这样:

private class Traverse implements Iterator {
    int pos = 0;
    boolean hasNextCalled = false;
    @Override
    public boolean hasNext() {
        hasNextCalled = true;
        if(pos<size()) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Card next() {
        return cards.get(pos++);
    }

    @Override
    public void remove() {
        if (!hasNextCalled) {
            throw new IllegalStateException("hasNext() must be called before remove()");
        }
        if(pos<1) {
            throw new IllegalStateException();
        }
       cards.remove(--pos);
       hasNextCalled = false;
    }

}

然后通过创建一个新的Traverse对象然后覆盖所有方法来实现第二个迭代器:

public Iterator OddEvenIterator() {
    Iterator it = new Traverse(){
        private int pos = 0;
        boolean hasNextCalled = false;

        @Override
        public boolean hasNext() {
            hasNextCalled = true;
            if (pos < size()) {
                return true;
            } else {
                return false;
            }
        }

        @Override
        public Card next() {
            Card nextCard = cards.get(pos);
            pos+=2;
            boolean moreCards = hasNext();
            if(moreCards==false) {
                pos=1;
            }
            return nextCard;
        }

        @Override
        public void remove() {
            if (!hasNextCalled) {
                throw new IllegalStateException("hasNext() must be called before remove()");
            }
            if (pos < 1) {
                throw new IllegalStateException();
            }
            pos-=2;
            cards.remove(pos);
            hasNextCalled = false;
        }
    };
    return it;      
}

我不记得为什么我这样做但感觉这是一种糟糕的方式。我想知道这两种方法之间是否存在任何有效差异?

1 个答案:

答案 0 :(得分:2)

第二种方法创建一个扩展Traverse的匿名类,这意味着您可以访问其成员(当然,考虑到正常的可见性规则)。但是你然后shadow Traverse声明了两个成员,这意味着匿名类不会使用它们。

鉴于您定义了每个Iterator方法并且返回值的类型为Iterator,除非您需要访问,否则没有理由扩展类而不是直接实现Iterator该类提供的一些成员。由于在这种情况下您没有,因此没有理由扩展Traverse

此外,Traverse没有定义除Iterator方法之外的任何方法,因此在向下转换从OddEvenIterator返回到{{1}的迭代器时甚至没有任何用处}}。如果有,那可能是扩展它的理由 - 虽然它也会有代码味道。

扩展Traverse的唯一其他原因是,如果其他一些代码使用反射来检查Traverse的子类型(包括使用Traverse)。这又可能是代码味道 - 但这是一种可能性。

我建议有一些风格,btw:

  • 您应该使用generics而不是原始instanceof类型
  • 大多数Java约定都有方法名称从低层开始(Iterator
  • 位于oddEvenIterator(),而不是hasNext,您只能if-else。这更简单,也更好。