【问题标题】:What are the Advantages of Enhanced for loop and Iterator in Java?Java中增强的for循环和迭代器有什么优势?
【发布时间】:2023-03-30 10:52:01
【问题描述】:

谁能告诉我增强的for循环和Java +5迭代器的优点是什么?

【问题讨论】:

    标签: java foreach


    【解决方案1】:

    增强的 for 循环具有以下主要优势:

    for (int i=0; i <= list.size(); i++)
    

    它消除了在上述非增强版本的每次迭代中重复计算list.size()。这是一个重要的性能优势。

    或者,您可以使用附加变量按如下方式计算循环外的大小:

    int size = list.size();
    for (int i=0; i <= size; i++)
    

    【讨论】:

    • 无论如何编译器肯定会为你做这件事,降低代码的可读性没有任何好处。
    • Bo,我提倡使用增强的for循环。你是说旧样式更具可读性?
    • 不,我是说将 list.size() 移到循环外会降低代码的可读性,而不会提高性能。
    • 这就是为什么我说使用 for(Type type: list) 而不是 for(int i=0; i
    • 我更喜欢 for(int i = 0, ii = list.size(); i
    【解决方案2】:

    我认为在介绍它的文档页面here 中已经总结了这一点。

    迭代一个集合比它需要的更丑

    真的..

    迭代器很混乱。此外,这是犯错的机会。迭代器变量在每个循环中出现 3 次:这是两次出错的机会。 for-each 结构消除了混乱和出错的机会。

    没错

    当您看到冒号 (:) 时,将其读作“in”。上面的循环读作“对于 c 中的每个 TimerTask t”。如您所见,for-each 构造与泛型完美结合。它保留了所有类型的安全性,同时消除了剩余的混乱。因为您不必声明迭代器,所以您不必为它提供通用声明。 (编译器会在你背后为你做这件事,但你不必关心它。)

    我想总结一下,但我认为该页面做得非常完美。

    【讨论】:

    • 链接现在失效了——你有机会更新它吗?谢谢!
    【解决方案3】:

    Stephen Colebourne(Joda-Time、JSR-310 等)Enhanced for each loop iteration control 提议在 Java 7 中扩展它的优点和缺点都得到了很好的总结:

    功能摘要:

    扩展 Java 5 for-each 循环以允许访问 循环索引,这是否是第一个 或最后一次迭代,并删除 当前项目。

    主要优势

    for-each 循环几乎可以肯定是最新的 Java 5 中的流行特性。它有效 因为它增加了抽象 水平 - 而不是必须表达 如何循环的低级细节 围绕列表或数组(带有索引 或迭代器),开发人员只需 表示他们想要循环并且 语言负责其余的工作。 然而,所有的好处都失去了,因为 只要开发者需要访问 索引或删除项目

    每项工作的原始 Java 5 相对保守的立场 旨在解决的问题数量 80% 的情况。然而,循环是这样的 编码中的常见形式 剩下的 20% 没有解决 代表大量代码。

    转换循环的过程 从 for each 要索引或 基于迭代器是痛苦的。这是 因为旧的循环样式 if 显着降低,更多 冗长而不清晰。也是 痛苦,因为大多数 IDE 不支持 这种“去重构”。

    主要好处:

    一个常见的编码习语表示为 比现在更高的抽象。 这有助于可读性和清晰度

    ...

    总而言之,增强的 for 循环提供了一种简洁的高级语法来循环列表或数组,从而提高了清晰度和可读性。但是,它遗漏了一些部分:允许访问索引循环或删除项目。

    另见

    【讨论】:

    • 这是一个不错的提议。让我想起了 LoopTagStatus,它在 JSTL c:forEach 中已经存在很长时间了。
    • @BalusC:是的,确实,我可以看到相似之处。我也认为这是一个不错的提议。但是我没有检查确切的状态,不确定它是否会被包括在内。
    【解决方案4】:

    主要缺点是创建了一个迭代器,它没有基于索引的循环。 这通常没问题,但在性能关键部分(例如,在实时应用程序中,当它必须每秒运行数百次时),它可能会导致主要的 GC 干预......

    【讨论】:

    • 如果您考虑其含义,这里的这个答案价值数百万美元!重述:当您使用 for-in 循环时,Java 会隐式构造一个 Iterator 对象,用于迭代可迭代对象。这意味着,如果您在代码的繁忙部分使用 for-in,您最终会在堆中收集大量垃圾,以便从所有这些创建的幻像迭代器中收集,并且您将遭受巨大的性能打击.高 AbstractList$Itr 对象计数出现在分析器中。不要在性能敏感的代码中使用 for-in 循环,使用 for-index 循环!
    【解决方案5】:

    更简洁。唯一的问题是空检查。

    for (String str : strs) {  // make sure strs is not null here
        // Do whatever
    }
    

    【讨论】:

    • 这当然不是问题:我可以有一个对象列表或数组在某些索引处具有空值,但我讨厌无法迭代它们。如果我不喜欢 null,我也可以这样做:if (str==null) continue;
    【解决方案6】:

    foreach/增强的 for/for 循环用于在数据对象上提供光标。当您考虑“逐行遍历文件”或“逐记录遍历结果集”时,这特别有用,因为它易于实现。

    与基于索引的方法相比,这还提供了一种更通用和改进的迭代方式,因为调用者(for 循环)不再需要知道如何获取值或集合大小或其他实现细节。

    【讨论】:

      【解决方案7】:

      正如其他人所说,增强的 for 循环提供了更简洁的语法、可读的代码和更少的类型。

      另外,它也避免了可能的“索引超出范围”错误情况。例如,当您手动迭代列表时,您可能会以错误的方式使用索引变量,例如:

      for(int i=0; i<= list.size(); i++)
      

      这将引发异常。但是在增强 for 循环的情况下,我们将迭代任务留给编译器。它完全避免了错误情况。

      【讨论】:

        【解决方案8】:

        您可以迭代任何可迭代的集合以及数组。 而且性能差异根本不是您应该担心的。

        可读性很重要。

        Prefer this    
        for (String s : listofStrings) 
            {
             ... 
            }
        
        over
        
            for (Iterator<String> iter = listofStrings.iterator(); iter.hasNext(); )
            {
             String s = iter.next();
             ...
            }
        

        注意,如果需要在迭代时删除元素,则需要使用Iterator

        例如,

        List<String> list = getMyListofStrings(); 
        
            for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) 
            {
                String s = iter.next();
                if (someCondition) {
                    iter.remove(); 
                }
            }
        

        您不能使用for(String s : myList) 删除列表中的元素。
        还要注意,在遍历数组时,foreach(或增强的for)只能用来获取元素,不能修改数组中的元素。
        如需更多信息,请参阅this

        【讨论】:

          【解决方案9】:

          对我来说,很明显,主要优势是可读性。

          for(Integer i : list){
             ....
          }
          

          明显比

          for(int i=0; i < list.size(); ++i){
            ....
          }
          

          【讨论】:

          • 您还需要添加一行来提取值。优点是它消除了许多简单的样板和其中的任何错误。毕竟,有大量代码只是以一种或另一种方式对集合进行迭代。
          【解决方案10】:

          少打字!加上来自编译器的更多帮助

          【讨论】:

            【解决方案11】:

            正如其他人已经回答的那样,它是更清洁的语法糖。如果你比较类迭代器循环,你会发现你需要声明的变量少了一个。

            【讨论】:

              【解决方案12】:

              更简洁的语法! 从性能的角度来看没有区别,因为这只是对程序员的一种方便。

              【讨论】:

              • 事实上,增强的 for 循环在很多情况下可能会慢一点。但这是可以忽略的。
              • 哦,我不知道。只是好奇在什么情况下..任何指针/引用?
              • 我的理解(但我可能错了)增强的 for 循环编译为与常规 for 循环相同的字节码。如果这是正确的,那么运行时行为应该是相同的。
              猜你喜欢
              • 2015-11-03
              • 2016-01-05
              • 2010-09-22
              • 1970-01-01
              • 2022-01-21
              • 2014-11-16
              • 2013-06-14
              • 2012-07-25
              • 2011-01-20
              相关资源
              最近更新 更多