【问题标题】:what is the performance efficient method for iterate java collection?迭代java集合的性能高效方法是什么?
【发布时间】:2015-12-21 08:51:39
【问题描述】:

我想了解迭代器设计模式,并在以下教程中找到。

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 循环。

当应用程序足够小并且性能是优先级时,这可以吗?还是可以优化代码?

【问题讨论】:

    标签: java collections iterator


    【解决方案1】:

    Iterator 的性能取决于它的实现。每个 Java 集合都有自己的迭代器实现,因此性能会有所不同。通常hasNextnext 方法没有循环。您显示的代码是教程中的一些特殊迭代器,它在执行过滤时进行迭代。虽然您有两个嵌套循环,但实际上您只遍历了底层集合channels 一次,因为position 不断地从0 增加到channels.size()hasNext() 内部循环是跳过不需要的项目所必需的,但它不会增加计算难度。这种迭代的总体难度是O(channels.size())

    请注意,此迭代器实现违反了Iterator 接口协定。首先它不会在迭代结束时抛出NoSuchElementException。其次,如果你多次调用next()而不调用hasNext(),你会得到不同的结果。因此,我不建议在实际代码中使用本教程中的示例。

    【讨论】:

    • 感谢@Tagir Valeev 的解释,现在我真的很好奇 hasNext() 和 next() 在 Java 集合中是如何工作的?
    • @AMY,检查 Java 源代码。例如here'sArrayList 迭代器。
    • 是的,我浏览了您建议的链接。 hasNext() 方法中的代码“return cursor != size;”消除所有疑虑。
    【解决方案2】:

    “使用 while 循环两次”是什么意思?如果您担心是否对集合进行两次迭代,那么在我看来并非如此。迭代器保留一个位置指针,在这两种方法中似乎只向前。所以虽然你确实有嵌套循环(一个在应用程序代码中,在 hasNext() 方法中),但它们不会获取相同的项目

    【讨论】:

    • 谢谢@sharonbn,我明白了。位置指针是keep go foreword,hasNext()方法中的while循环没有完全迭代。
    【解决方案3】:

    收藏

    如果channels 是某种Iterable,那么你可以把循环写成

    for(Channel c : channels) {
      if(c.getTYPE().equals(type) 
        || type.equals(ChannelTypeEnum.ALL)) {
           return true;
      }
    }
    return false;
    

    如果您仅将该位置用于迭代到下一个元素,则无需增加位置。

    这只是简写 - 使用 cmets 中所述的迭代器的代码 - 因此它不会在性能方面获得太多收益,但会增加代码的清晰度。如果您的channels 的类型已经 Collection 并实现Iterable

    ,则不需要像在上面的代码中那样实现您的自己的 迭代器

    【讨论】:

    • 这只是编译器使用迭代器的简写
    猜你喜欢
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    • 2020-07-18
    • 2019-08-31
    相关资源
    最近更新 更多