作为Java语言的新手,我试图熟悉遍历列表(或其他集合)的所有方法(或至少是非病态的方法)以及每种方法的优缺点。
给定一个List<E> list
对象,我知道以下方法来遍历所有元素:
while
/ do while
循环)// Not recommended (see below)!
for (int i = 0; i < list.size(); i++) {
E element = list.get(i);
// 1 - can call methods of element
// 2 - can use 'i' to make index-based calls to methods of list
// ...
}
注:正如@amarseillan指出的,这种形式是一个糟糕的选择
迭代List
s,因为的实际实现
get
方法可能不如使用Iterator
方法有效。
例如,LinkedList
实现必须遍历所有的
在I之前的元素获取第I个元素
在上面的例子中,List
实现没有办法
“保存其位置”以使未来的迭代更有效。
对于ArrayList
,这并不重要,因为get
的复杂度/代价是常数时间(O(1)),而对于LinkedList
,它与列表的大小(O(n))成正比。< / p >
有关内置Collections
实现的计算复杂性的更多信息,请查看这个问题。
for (E element : list) {
// 1 - can call methods of element
// ...
}
for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// ...
}
for (ListIterator<E> iter = list.listIterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// 3 - can use iter.add(...) to insert a new element into the list
// between element and iter->next()
// 4 - can use iter.set(...) to replace the current element
// ...
}
list.stream().map(e -> e + 1); // Can apply a transformation function for e
(一个来自Java 8的流API的映射方法(参见@i_am_zero的答案)。)
在Java 8实现Iterable
(例如,所有# eyz1)的集合类中,现在有一个forEach
方法,可以用来代替上面演示的For循环语句。(这里是另一个问题,提供了一个很好的比较。)
Arrays.asList(1,2,3,4).forEach(System.out::println);
// 1 - can call methods of an element
// 2 - would need reference to containing object to remove an item
// (TODO: someone please confirm / deny this)
// 3 - functionally separates iteration from the action
// being performed with each item.
Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
// Same capabilities as above plus potentially greater
// utilization of parallelism
// (caution: consequently, order of execution is not guaranteed,
// see [Stream.forEachOrdered][stream-foreach-ordered] for more
// information about this).
如果有的话,还有其他办法吗?
(顺便说一下,我的兴趣根本不是出于对优化性能的渴望;我只是想知道作为开发人员,我有哪些表单可以使用。)