当我编写和发现用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());
}
}
答案 0 :(得分:18)
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);
答案 1 :(得分:2)
第一个更好,最不容易出错。
public void method1() {
System.out.println("Method 1");
int i = 1;
for (String value:list) {
System.out.println((i++) + " = " + value);
}
}
第二个选项与您正在使用的Collection紧密结合。这意味着,如果有人更改了数据结构,那么他/她也必须更改for循环的代码。
第三个选项,当你必须使用嵌套循环并且必须处理多个迭代器时,迭代器会变得丑陋。
查看以下链接,了解迭代器的错误使用情况。 https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html
答案 2 :(得分:-1)
method3()
使用Iterator
是迭代列表的最佳方式。即使method1()
在幕后使用Iterator
,如果您想修改循环内的列表,例如更新或删除,也可能会导致ConcurrentModificationException
。
答案 3 :(得分:-3)
他们都不是。使用java中提供的lambda表达式。
或者Guava函数,如果使用Java&lt; 8。