简体   繁体   English

Java:遍历集合的最佳方式(此处为 ArrayList)

[英]Java: Best way to iterate through a Collection (here ArrayList)

Today I was happily coding away when I got to a piece of code I already used hundreds of times:今天,当我找到一段我已经使用过数百次的代码时,我正在愉快地编码:

Iterating through a Collection (here ArrayList)遍历一个集合(这里是 ArrayList)

For some reason, I actually looked at the autocompletion options of Eclipse and it got me wondering:出于某种原因,我实际上查看了 Eclipse 的自动完成选项,这让我想知道:

What cases are the following loops better to use than the others?以下循环在哪些情况下比其他循环更适合使用?

The classic array index loop:经典的数组索引循环:

for (int i = 0; i < collection.length; i++) {
  type array_element = collection.get(index);
}

The Iterator hasNext()/next():迭代器 hasNext()/next():

for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
  type type = (type) iterator.next();   
}

And my favorite because its so simple to write:我最喜欢的是因为它写起来很简单:

for (iterable_type iterable_element : collection) {

}

The first one is useful when you need the index of the element as well.当您还需要元素的索引时,第一个很有用。 This is basically equivalent to the other two variants for ArrayList s, but will be really slow if you use a LinkedList .这基本上等同于ArrayList的其他两个变体,但如果使用LinkedList会非常慢。

The second one is useful when you don't need the index of the element but might need to remove the elements as you iterate.当您不需要元素的索引但可能需要在迭代时删除元素时,第二个很有用。 But this has the disadvantage of being a little too verbose IMO.但这样做的缺点是 IMO 有点过于冗长。

The third version is my preferred choice as well.第三个版本也是我的首选。 It is short and works for all cases where you do not need any indexes or the underlying iterator (ie you are only accessing elements, not removing them or modifying the Collection in any way - which is the most common case).它很短,适用于不需要任何索引或底层迭代器的所有情况(即您只访问元素,而不是删除它们或以任何方式修改Collection - 这是最常见的情况)。

All of them have there own uses:它们都有自己的用途:

  1. If you have an iterable and need to traverse unconditionally to all of them:如果您有一个可迭代对象并且需要无条件遍历所有对象:

    for (iterable_type iterable_element : collection) for (iterable_type iterable_element : 集合)

  2. If you have an iterable but need to conditionally traverse:如果您有一个可迭代但需要有条件地遍历:

    for (Iterator iterator = collection.iterator(); iterator.hasNext();) for (Iterator iterator = collection.iterator(); iterator.hasNext();)

  3. If data-structure does not implement iterable:如果数据结构没有实现可迭代:

    for (int i = 0; i < collection.length; i++) for (int i = 0; i < collection.length; i++)

There is additionally collections' stream() util with Java 8 Java 8 中还有集合的 stream() 实用程序

collection.forEach((temp) -> {
            System.out.println(temp);
});

or或者

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

More information about Java 8 stream and collections for wonderers link有关 Java 8 流和 Wonderers 集合的更多信息链接

None of them are "better" than the others.他们中没有一个比其他人“更好”。 The third is, to me, more readable, but to someone who doesn't use foreaches it might look odd (they might prefer the first).第三个对我来说更具可读性,但对于不使用 foreaches 的人来说,它可能看起来很奇怪(他们可能更喜欢第一个)。 All 3 are pretty clear to anyone who understands Java, so pick whichever makes you feel better about the code.任何了解 Java 的人都非常清楚所有 3 种方法,因此请选择让您对代码感觉更好的那个。

The first one is the most basic, so it's the most universal pattern (works for arrays, all iterables that I can think of).第一个是最基本的,所以它是最通用的模式(适用于数组,我能想到的所有可迭代对象)。 That's the only difference I can think of.这是我能想到的唯一区别。 In more complicated cases (eg you need to have access to the current index, or you need to filter the list), the first and second cases might make more sense, respectively.在更复杂的情况下(例如,您需要访问当前索引,或者您需要过滤列表),第一种和第二种情况可能分别更有意义。 For the simple case (iterable object, no special requirements), the third seems the cleanest.对于简单的情况(可迭代对象,没有特殊要求),第三个似乎最干净。

The first option is better performance wise (As ArrayList implement RandomAccess interface).第一个选项是更好的性能(因为 ArrayList 实现了 RandomAccess 接口)。 As per the java doc, a List implementation should implement RandomAccess interface if, for typical instances of the class, this loop:根据 java 文档,如果对于类的典型实例,此循环,则 List 实现应实现 RandomAccess 接口:

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

runs faster than this loop:运行速度比这个循环快:

 for (Iterator i=list.iterator(); i.hasNext(); )
     i.next();

I hope it helps.我希望它有帮助。 First option would be slow for sequential access lists.对于顺序访问列表,第一个选项会很慢。

Here is an example这是一个例子

Query query = em.createQuery("from Student");
             java.util.List list = query.getResultList();
             for (int i = 0; i < list.size(); i++) 
             {

                 student = (Student) list.get(i);
                 System.out.println(student.id  + "  " + student.age + " " + student.name + " " + student.prenom);

             }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM