遍历列表,更好的方法
Posted
技术标签:
【中文标题】遍历列表,更好的方法【英文标题】: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());
【问题讨论】:
Ways to iterate over a List in java? 的可能重复项 Kenster,感谢您让我知道可能的重复。我的问题更倾向于使用索引输出。但我/我们还发现,在 Java 8 的新版本中,现在有了新的遍历列表的方法。 您想知道哪个更好,但没有提供评估哪个更好的标准。 【参考方案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->System.out.println((index++)+" = "+e));
你也可以打印索引
@Loki 不,lambda 中的变量必须是有效的最终变量。你可以使用AtomicInteger
,虽然它有点矫枉过正。
你是对的。不过我留下评论,所以每个人都可以像我一样学习
根据您关于使用迭代器删除元素的评论,在迭代列表时更改列表不是一件坏事吗?坏事可能会在你的脸上爆炸,但有例外。
@Davor 不是通过迭代器的 remove 方法。文档states “请注意,Iterator.remove 是在迭代期间修改集合的唯一安全方法;如果在迭代过程中以任何其他方式修改基础集合,则行为未指定。”我>【参考方案4】:
没有。使用 lambda 表达式,在 java 8 中可用。
如果使用 Java
【讨论】:
您能否提供更多细节或示例?这是一个低质量的答案以上是关于遍历列表,更好的方法的主要内容,如果未能解决你的问题,请参考以下文章