5

I have worked pretty much on collection but I have few doubts.

I am aware that we can iterate list with iterator.

Another way is that we can go through as below:

for(int i=0; i<list.size(); i++){
   list.get(i);
}

Here I think there is problem that each time it will call list.size() that will build whole tree that will impact performance.

I thought other solution as well like:

int s = list.size();
for(int i=0; i<s; i++){
  list.get(i);
}

I think this can solve the problem. I am not much exposed to thread. I am thinking that whetherthis should be right approach or not.

Another way I thought is like:

for (Object obj; list){

}

With this new for loop, I think compiler again checks size of list.

Please give best solution from these or alternative performance efficient approach. Thank you for your help.

Nimesh
  • 794
  • 3
  • 8
  • 18

4 Answers4

7

Calling size() at each iteration is not really a problem. This operation is O(1) for all the collections I know of: size() simply returns the value of a field of the list, holding its size.

The main problem of the first way is the repeated call to get(i). This operation is O(1) for an ArrayList, but is O(n) for a LinkedList, making the whole iteration O(n2) instead of O(n): get(i) forces the list to start from the first element of the list (or the last one), and to go to the next node until the ith element.

Using an iterator, or using a foreach loop (which internally uses an iterator), guarantees that the most appropriate way of iterating is used, because the iterator knows about how the list is implemented and how best go from one element to the next.

BTW, this is also the only way to iterate through non-indexed collections, like Sets. So you'd better get used to use that kind of loop.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • And what about new for loop? – Nimesh Apr 11 '15 at 07:57
  • that's what I mean with "foreach loop". It uses an iterator internally. I tend to avoid calling that the "new for loop", as it's not new at all. It's 10 years old. – JB Nizet Apr 11 '15 at 07:59
  • Yes but for identity perspective we call it new for loop – Nimesh Apr 11 '15 at 08:03
  • The proper term, used by the Java Language Specification, is "The enhanced for statement". But believe it or not, it's commonly referred to as the foreach loop. See for example: https://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html – JB Nizet Apr 11 '15 at 08:08
  • http://howtodoinjava.com/2013/03/26/performance-comparison-of-different-for-loops-in-java/ this blog says that iterator is slow – Nimesh Apr 11 '15 at 08:10
  • Yes, but the author can't do a benchmark properly. That is hard, and his benchmark is completely flawed. – JB Nizet Apr 11 '15 at 08:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/74994/discussion-between-naman-and-jb-nizet). – Nimesh Apr 11 '15 at 08:13
  • You can call .size() or just use a variable for it. It dosn't matter, because the complexity of both is O(1) (for ArrayList). The other List implementation can use own callculation for .size(). – CyberAleks Apr 11 '15 at 08:13
6

For your example is the best way:

for (Object obj: list){

}

It is the same like in java version < 1.5:

for (Iterator it = hs.iterator() ; it.hasNext() ; ){}

It use iterator of collection. You actually don't need the size of collection. The .size() method is should actually don't build the tree, but .get() can loops to the given element. .get() and .size() methods depend on List implementation. .get() In ArrayList should be actually O(1) complexity and not O(n)

UPDATE

In java 8 you can use:

myList.forEach{ Object elem -> 
 //do something
}
CyberAleks
  • 1,545
  • 1
  • 14
  • 17
1

The best way to iterate the list in terms of performance would be to use iterators ( your second approach using foreach ). If you are using list.get(i), it's performance would depend upon the implementation of the list. For ArrayList, list.get(i) is O(1) where as it's O(n) for LinkedList.

Also, list.size() is O(1) and should not have any impact over the performance.

Mohit Gupta
  • 649
  • 1
  • 7
  • 15
  • what would be the time complexity involved for forEach ?. If its O(n) why don't designers go for O(log n) ? – balboa_21 May 30 '17 at 19:39
1
for (Object obj: list){

}

Above code for me is the best way, it is clean and can be read easily.

The forEach in Java 8 is nice too.

shepard23
  • 148
  • 2
  • 13