【问题标题】:Looping through lists, better method遍历列表,更好的方法
【发布时间】:2015-05-27 18:23:30
【问题描述】:

当我在 Java 中编码和发现新的做事方式时,我总是对通过列表循环输出数据的更好方法感到困惑。

在下面的示例中,我正在遍历列表并使用一个计数器,所以很多时候我不得不在输出中包含一个索引计数器。

我偏爱方法 1,但我发现这些方法中的任何一种都有些过时了。我见过很多循环遍历列表的例子,主要使用的是方法 2。

所以我的问题是什么是更好的方法,如果所有这些方法都一样,那么最标准的是什么?

private ArrayList<String> list = new ArrayList<String>();

public Test() {
    list.add("One");        
    list.add("Two");        
    list.add("Three");      
    list.add("Four");       
    list.add("Five");

    method1();
    method2();
    method3();
}

public void method1() {
    System.out.println("Method 1");
    int i = 1;
    for (String value:list) {
        System.out.println((i++) + " = " + value);
    }
}

public void method2() {
    System.out.println("Method 2");
    for (int i = 0; i < list.size(); i++) {
        System.out.println((i+1) + " = " + list.get(i));
    }
}

public void method3() {
    System.out.println("Method 3");
    Iterator<String> it = list.iterator();
    int i = 1;
    while (it.hasNext()) {
        System.out.println((i++) + " = " + it.next());
    }
}

【问题讨论】:

  • Kenster,感谢您让我知道可能的重复。我的问题更倾向于使用索引输出。但我/我们还发现,在 Java 8 的新版本中,现在有了新的遍历列表的方法。
  • 您想知道哪个更好,但没有提供评估哪个更好的标准。

标签: java loops arraylist


【解决方案1】:

method3() 使用Iterator 是遍历列表的最佳方式。尽管method1()在幕后使用Iterator,但如果你想在循环内修改列表,比如更新或删除,可能会导致ConcurrentModificationException

【讨论】:

    【解决方案2】:

    第一个更好,更不容易出错。

    public void method1() {
        System.out.println("Method 1");
        int i = 1;
        for (String value:list) {
            System.out.println((i++) + " = " + value);
        }
    }
    

    第二个选项与您正在使用的集合紧密耦合。这意味着,如果有人更改了数据结构,那么他/她也必须更改 for 循环的代码。

    第三个选项,当你必须使用嵌套循环并且必须处理多个迭代器时,迭代器会变得很丑。

    查看以下链接,了解迭代器容易出错的用法。 https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html

    【讨论】:

      【解决方案3】:

      method1() 类似于method3(),因为 for-each 循环在后台使用 List 的迭代器。与method3() 的不同之处在于您实际上可以访问此迭代器,因此如果您希望从列表中删除元素,可以对其调用 remove。

      另一方面,method2() 可能会导致“糟糕”的性能,具体取决于底层实现。如果您的列表是LinkedList,则get 具有O(n) 复杂度时间,因此for 循环将具有O(n^2) 复杂度。使用迭代器,您将始终在恒定时间内获得下一个元素。

      我个人会使用 1,它编写的代码也更少,如果您的意图是对数据结构执行只读操作,这是 for-each 循环的主要好处之一。

      如果您使用的是 Java 8 并且不需要打印索引,您也可以这样做:

      list.forEach(System.out::println);
      

      【讨论】:

      • int index = 1; list.forEach(e-&gt;System.out.println((index++)+" = "+e));你也可以打印索引
      • @Loki 不,lambda 中的变量必须是有效的最终变量。你可以使用AtomicInteger,虽然它有点矫枉过正。
      • 你是对的。不过我留下评论,所以每个人都可以像我一样学习
      • 根据您关于使用迭代器删除元素的评论,在迭代列表时更改列表不是一件坏事吗?坏事可能会在你的脸上爆炸,但有例外。
      • @Davor 不是通过迭代器的 remove 方法。文档states “请注意,Iterator.remove 是在迭代期间修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改基础集合,则行为未指定。”我>
      【解决方案4】:

      没有。使用 lambda 表达式,在 java 8 中可用。

      如果使用 Java

      【讨论】:

      • 您能否提供更多细节或示例?这是一个低质量的答案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 2021-11-08
      • 2014-06-14
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      相关资源
      最近更新 更多