我回头看了一些写在不同迭代器需要的地方的代码,我注意到我像平常一样写了第一个迭代器:
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;
}
我不记得为什么要这么做了,但是这样做感觉很糟糕。我想知道这两种方法之间是否有有效的区别?
第二种方法创建了一个extends匿名类Traverse
,这意味着您可以访问其成员(当然要考虑正常的可见性规则)。但是你再影子,这两个成员Traverse
宣称,这意味着匿名类不会使用它们。
假设您定义了每个Iterator
方法,并且返回值的类型为Iterator
,则没有理由扩展类而不是Iterator
直接实现,除非您需要访问该类提供的某些成员。由于您在这种情况下不这样做,因此没有理由进行扩展Traverse
。
此外,Traverse
除了这些Iterator
方法外,没有定义其他任何方法,因此在向下转换从OddEvenIterator
到返回的迭代器时甚至没有任何用处Traverse
。如果有的话,那可能就是扩展它的原因-尽管这也可能是代码的味道。
扩展的唯一其他原因Traverse
是其他一些代码是否使用反射来检查的子类型Traverse
(包括使用instanceof
)。再次,这可能是代码的味道-但这是有可能的。
我会建议一些风格方面的事情,顺便说一句:
Iterator
类型oddEvenIterator()
)hasNext
而不是在if-else
,你可以return pos < size()
。这比较简单,并且始终是可取的。本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句