我正在回顾一下我写的一些代码,我需要不同的迭代器,我注意到我正常编写第一个迭代器,就像这样:
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;
}
我不记得为什么我这样做但感觉这是一种糟糕的方式。我想知道这两种方法之间是否存在任何有效差异?
答案 0 :(得分:2)
第二种方法创建一个扩展Traverse
的匿名类,这意味着您可以访问其成员(当然,考虑到正常的可见性规则)。但是你然后shadow Traverse
声明了两个成员,这意味着匿名类不会使用它们。
鉴于您定义了每个Iterator
方法并且返回值的类型为Iterator
,除非您需要访问,否则没有理由扩展类而不是直接实现Iterator
该类提供的一些成员。由于在这种情况下您没有,因此没有理由扩展Traverse
。
此外,Traverse
没有定义除Iterator
方法之外的任何方法,因此在向下转换从OddEvenIterator
返回到{{1}的迭代器时甚至没有任何用处}}。如果有,那可能是扩展它的理由 - 虽然它也会有代码味道。
扩展Traverse
的唯一其他原因是,如果其他一些代码使用反射来检查Traverse
的子类型(包括使用Traverse
)。这又可能是代码味道 - 但这是一种可能性。
我建议有一些风格,btw:
instanceof
类型Iterator
)oddEvenIterator()
,而不是hasNext
,您只能if-else
。这更简单,也更好。