views:

162

answers:

9

In my program I often use collections to store lists of objects. Currently I use ArrayList to store objects. My question is: is this a best choice? May be its better to use LinkedList? Or something else?

Criteria to consider are:

  • Memory usage
  • Productivity

Operations which I need are:

  • Add element to collection
  • Iterate through the elements

Any thoughts?

Update: my choice is : ArrayList :) Basing on this discussion as well as the following ones:

A: 

Linked list is faster for adding/removing inside elements (ie not head or tail)

Arraylist is faster for iterating

Maxime ARNSTAMM
Hm. Maybe it's faster when iterating, though I don't expect this to be more than marginal. The real benefit should be with accessing elements in random order...
Dirk
As I understand both have O(n) iteration.
Qwerky
O(n) iteration over N elements. Linked list iterator will not throw if you read here and change way over there...
GregC
A: 

It's a classic tradeoff between insert vs. retrieve optimization. Common choice for the task as you describe it is the ArrayList.

GregC
Why its a common choice?
Andriy Sholokh
It's fast to iterate over whole collection, and there's less memory footprint since links in a linked list have to be stored somewhere.
GregC
A: 

ArrayList is fine for your (and most other) purposes. It has a very small memory overhead and has good amortized performance for most operations. The cases where it is not ideal are relatively rare:

  • The list ist very large
  • You frequently need to do one of these operations:
    • Add/remove items during iteration
    • Remove items from the beginning of the list
Michael Borgwardt
To elaborate on this point: ArrayList's iterator will throw an exception if it detects change while iterating. Also, remove from the beginning a-la queue is better accomplished via linked list for obvious reasons.
GregC
@GregC: A LinkedList's iterator does not throw exceptions when there are concurrent modifications? If so, why is that good?
Thilo
It appears I am wrong... Will have to try it.... quoting: "The iterators returned by the this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the Iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future. "
GregC
My thoughts were... If somebody is modifying the list, and they aren't changing anything just to the left or right of the element being iterated over, then there is no problem.
GregC
@GregC: that sounds logical at first glance, but race conditions aren't that simple. You misunderstood my point though: the Iterator (and ListIterator) interfaces themselves have add/remove methods that can be used safely to modify the list during iteration (and efficiently so, for LinkedList)
Michael Borgwardt
A: 

If you're only adding at the end of the list, ArrayList should be ok. From the documentation of ArrayList:

The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost

and ArrayList should also use less memory than a linked list as you don't need to use space for the links.

Andre Holzner
+2  A: 

I always default to ArrayList, and would in your case as well, except when

  • I need thread safety (in which case I start looking at List implementations in java.util.concurrent)
  • I know I'm going to be doing lots of insertion and manipulation to the List or profiling reveals my usage of an ArrayList to be a problem (very rare)

As to what to pick in that second case, this SO.com thread has some useful insights: http://stackoverflow.com/questions/1713144/java-lists-does-linkedlist-really-perform-so-poorly-vs-arraylist-and-treelist

whaley
Thank you for the link to a very interesting discussion!
Andriy Sholokh
how is a LinkedList more thread-safe?
Thilo
@Thilo - I never said it was. I said I default to ArrayList unless I need thread safety. Just to make it crystal clear, I'll modify my answer to say I go to the List implementations in java.util.concurrent.
whaley
A: 

It depends on your usage profile.

Do you add to the end of the list? Both are fine for this. Do you add to the start of the list? LinkedList is better for this. Do you require random access (will you ever call get(n) on it)? ArrayList is better for this.

Both are good at iterating, both Iterator implementations are O(1) for next().

If in doubt, test your own app with each implementation and make your own choice.

Qwerky
A: 

I know I'm late but, maybe, this page can help you, not only now, but in the future...

SoulWanderer
A: 

I guess this would be a good start: http://www.odi.ch/prog/design/newbies.php#26 It shows differences in performance of different implementations of List.

Andrzej Bobak
A: 

Given your criteria, you should be using the LinkedList.

LinkedList implements the Deque interface which means that it can add to the start or end of the list in constant time (1). In addition, both the ArrayList and LinkedList will iterate in (N) time.

You should NOT use the ArrayList simply because the cost of adding an element when the list is full. In this case, adding the element would be (N) because of the new array being created and copying all elements from one array to the other.

Also, the ArrayList will take up more memory because the size of your backing array might not be completely filled.

javaman
My colleague has just wrote a simple test - adding elements to lists of different size in different places. And here is the result:Have made my own unpretentious test. Here are result:- Simple adding ( List.add(“A”)): ArrayList faster than LinkedList 3-5 time on range of size from 1 to 100 000.
Andriy Sholokh
Adding to the head of list (List.add(0, “A”): At size 1 the time is equal; At size 100 LinkedList faster ~2 times; At size 1000 LinkedList faster ~10 times; At size 10000 LiskedList faster ~50 times; At size 50000 LinkedList faster ~80 times
Andriy Sholokh
Random adding (List.add(Math.random(list.size()), “A”)):ArrayList faster than LinkedList 2 times on the same range (1 to 100 000)
Andriy Sholokh
So, @rrlichwa, unfortunately, I can't agree with you regarding productivity :(
Andriy Sholokh
@rrlichwa, regarding memory usage, I believe ArrayList uses memory more compactly, as it does not save any internal service stuff (like link to the next element in LinkedList)
Andriy Sholokh