views:

827

answers:

9

When should I use an ArrayList in Java, and when should I use an array?

+5  A: 

ArrayLists are useful when you don't know in advance the number of elements you will need. Simple Example: you are reading a text file and builing a list of all the words you find. You can just keep adding to your array list, it will grow.

Arrays you need to pre-declare their size.

djna
+3  A: 

An array has to be declared with a fixed size therefore you need to know the number of elements in advance.

An ArrayList is preferable when you don't know how many elements you will need in advance as it can grow as desired.

An ArrayList may also be preferable if you need to perform operations that are available in its API that would required manual implementation for an array. (e.g. indexOf)

Mark
+8  A: 

Some differences:

  • Arrays are immutable in their size, you cannot easly remove and element and remove the hole whereas using an ArrayList is straightforward
  • Arrays are fast (handled directly by the JVM as special objects) than an ArrayList and requires less memory
  • Arrays have a nice syntax for accessing elements (e.g. a[i] vs a.get(i))
  • Arrays don't play well with generics (e.g. you cannot create a generic array)
  • Arrays cannot be easly wrapped as ArrayList (e.g. Collections utils like checkedList, synchronizedList and unmodifiableList)
  • declaring the ArrayList as List you can easly swap implementation with a LinkedList when you need; this imho is the best advantage over plain arrays
  • Array's toString, equals and hashCode are weird and error-prone, you must use Arrays class utilities
dfa
Why use an ArrayList all the time? If you have situations where you're Array doesn't need to expand, then why use the ArrayList? Or is the overhead for the ArrayList negligible?
pave
In most of the times I would say yes it is because it uses an Array in it implementation itself. It is more convenient to use the list and all the nice stuff that comes with the collections. If you have performance problems in the end you can see if the list really is the bottleneck and remove it.
Janusz
Much more useful than the ability to substitute LinkedList (which is very rarely needed) is the ability to use Collections.singletonList() and emptyList().
Michael Borgwardt
the idea is that ArrayList is more object-oriented than an Array, for the sake of this question I think that it is worty
dfa
You can't create a Generic array? You don't need to, it's already generic! Array of Things will only accept Things.
djna
class Foo<T> { T[] data = new T[10]; } <-- you cannot do that
dfa
+2  A: 

When you want to change its size by adding or removing elements.

When you want to pass it to something that wants a Collection or Iterable (although you can use Arrays.asList(a) to make an array, a, look like a List).

Nat
+5  A: 

Another couple of points:

  • You may want to consider using an array to represent more than one dimension (e.g. matrix).
  • Arrays can be used to store primitives and hence offer a more compact representation of your data than using an ArrayList.
Adamski
+1 they are both very good points
dfa
I'd rather have a matrix represented by an actual class with a proper interface. This might use a two-dimensional array internally so I'd agree on that use but not as a general interface for representing a matrix.
VoidPointer
@VoidPointer - In general I agree with you although it depends on how intensive the number-crunching was that I was performing.
Adamski
+1  A: 

I would say the default presumption should be to use an ArrayList unless you have a specific need, simply because it keeps your code more flexible and less error prone. No need to expand the declaration size when you add an extra element 500 lines of code away, etc. And reference the List interface, so you can replace the Array list with a LinkedList or a CopyOnWriteArrayList or any other list implementation that may help a situation without having to change a lot of code.

That being said, arrays have some properties that you just won't get out of a list. One is a defined size with null elements. This can be useful if you don't want to keep things in a sequential order. For example a tic-tac-toe game.

Arrays can be multi-dimensional. ArrayLists cannot.

Arrays can deal with primitives, something an ArrayList cannot (although there are third party collection classes that wrap primitives, they aren't part of the standard collections API).

Yishai
Java has autoboxing since Java 5 so you can add an int to an ArrayList<Integer> object.
VoidPointer
That is certainly true, but it does not aleviate the performance issues if you have a large array of them.
Yishai
+1 good points
dfa
+3  A: 

It's not only about the fact that arrays need to grow, a collection is easier to deal with.

Sometimes arrays are fine, when you just need to iterate over elements, read-only. However, most of the time you want to use methods like contains, etc.

You can't create generic arrays so it 'might' or might not bother you.

When in doubt, use Collections, it will make people that use your API love you :-). If you only provide them with arrays, the first lines of code that they'll write is :

Arrays.asList(thatGuyArray);
John Doe
Arrays.asList don't return an java.util.ArrayList but only a private class that is similar to ArrayList
dfa
yes, I am aware of it :-), but thanks for mentioning it, it might be helpful for someone.
John Doe
+3  A: 

The List interface, of which ArrayList is an implementation in the Java Collections Framework is much richer then what a plain Java array has to offer. Due to the relatively widespread support of the collection framework throughout Java and 3rd party libraries, using an ArrayList instead of an array makes sense in general. I'd only use arrays if there is really need for them:

  • They are required by some other interface I'm calling
  • Profiling shows a bottleneck in a situation where array access can yield a significant speedup over list access
  • Situations where an array feels more natural such as buffers of raw data as in

    byte[] buffer = new byte[0x400]; // allocate 1k byte buffer
    

You can always get an array representation of your ArrayList if you need one:

Foo[] bar = fooList.toArray(new Foo[fooList.size()])

It is a common failure pattern that methods return a reference to a private array member (field) of a class. This breaks the class' encapsulation as outsiders gain mutable access to the class' private state. Consequently you would need to always clone the array and return a reference to the cloned array. With an ArrayList you can use...

return Collections.unmodifiableList(privateListMember);

... in order to return a wrapper that protects the actual list object. Of course you need to make sure that the objects in the list are immutable too, but that also holds for a (cloned) array of mutable objects.

As per Nick Holt's comment, you shouldn't expose the fact that a List is an ArrayList anywhere:

private List<Foo> fooList = new ArrayList<Foo>();

public List<Foo> getFooList() {
    return Collections.unmodifiableList(fooList);
}
VoidPointer
I'd add in that you should depend on java.util.List, which allows you to swap the implementation pretty painlessly in most cases.
Nick Holt
Good point. I have added that to the answer.
VoidPointer
+1  A: 

G'day,

A couple of points that people seem to have missed so far.

  1. an array can only contain one type of object whereas an ArrayList is a container that can contain a mixture of object types, it's heterogeneous,
  2. an array must declare the type of its contents when the array itself is declared. An ArrayList doesn't have to declare the type of its contents when the ArrayList is declared,
  3. you must insert an item into a specific location in an array. Adding to an ArrayList is done by means of the add() method on the container, and
  4. objects are stored in an array and retain their type because of the way the array can only store objects of a particular type. Objects are stored in an ArrayList by means of the superclass type Object.

Edit: Ooop. Regarding the last point on the list, I forgot the special case where you have an array of Objects then these arrays can also contain any type of object. Thanks for the comment, Yishai! (-:

HTH

cheers,

Rob Wells
If you have an Object[] array, it can contain any kinds of Objects, just like an array list.
Yishai