我想知道迭代器的设计模式,并发现以下教程。
http://www.journaldev.com/1716/iterator-design-pattern-in-java-example-tutorial
下面是hasNext()
和next()
方法的代码。
@Override
public boolean hasNext() {
while (position < channels.size()) {
Channel c = channels.get(position);
if (c.getTYPE().equals(type) || type.equals(ChannelTypeEnum.ALL)) {
return true;
} else
position++;
}
return false;
}
@Override
public Channel next() {
Channel c = channels.get(position);
position++;
return c;
}
并使用上述方法集合迭代为
while (baseIterator.hasNext()) {
Channel c = baseIterator.next();
System.out.println(c.toString());
}
如果我们使用hasNext()
和next()
方法,看起来就像我们使用了两次while循环。
当应用程序足够小并且性能是优先考虑的时候,这可以吗?或者可以有优化的代码?
4条答案
按热度按时间sbdsn5lh1#
Iterator
的性能取决于它的实现。每个Java集合都有自己的迭代器实现,因此性能会有所不同。通常hasNext
和next
方法没有循环。您显示的代码是教程中的一些特殊迭代器,它在执行过滤时进行迭代。虽然您有两个嵌套循环,当position
不断从0增加到channels.size()
时,您实际上只遍历底层集合channels
一次。hasNext()
内部循环对于跳过不需要的项是必要的,但并不增加计算难度,这种迭代的总体难度为O(channels.size())
。注意,这个迭代器实现破坏了
Iterator
接口契约。首先,它在迭代结束时没有抛出NoSuchElementException
。其次,如果你多次调用next()
而没有调用hasNext()
,你将得到不同的结果。因此,我不建议在真实的代码中使用本教程中的示例。jxct1oxe2#
你说的“使用while循环两次”是什么意思?如果你关心你是否在集合上迭代两次,那么我不这么认为。迭代器保持一个位置指针,在两个方法中似乎只是前进。所以当你有嵌套的循环时(一个在应用程序代码中,在hasNext()方法中),它们不获取相同的项
kyks70gy3#
如果
channels
是某种Iterable
,则可以将循环编写为如果您只使用该位置迭代到下一个元素,则不需要递增位置。
这只是一个简短的代码--使用注解中所述的迭代器的代码--所以它不会在性能方面获得太多的好处,但是会增加代码的清晰度。如果你的
channels
类型已经是Collection
并且实现了Iterable
,那么就没有必要像上面的代码那样实现你自己的迭代器yptwkmov4#
这是迭代Set的最快方式:
在这个循环中,避免了在每一步都调用iteration.hasNext(),这就是为什么它比传统的迭代器循环快,也比增强的for循环快。
当然,差异非常小,只有当性能对代码确实非常重要时,才应该像这样优化。