views:

159

answers:

5

Well, it seems to me ArrayLists make it easier to expand the code later on both because they can grow and because they make using Generics easier. However, for multidimensional arrays, I find the readability of the code is better with standard arrays.

Anyway, are there some guidelines on when to use one or the other? For example, I'm about to return a table from a function (int[][]), but I was wondering if it wouldn't be better to return a List<List<Integer>> or a List<int[]>.

A: 

It mostly comes down to flexibility/ease of use versus efficiency. If you don't know how many elements will be needed in advance, or if you need to insert in the middle, ArrayLists are a better choice. They use Arrays under the hood, I believe, so you'll want to consider using the ensureCapacity method for performance. Arrays are preferred if you have a fixed size in advance and won't need inserts, etc.

ars
You can also use new ArrayList<T>(10) to get an initial size of 10. You have to watch out when using ArrayList's because they can fragment your memory if used carelessly. Each time an ArrayList runs out of space it allocates a brand new primitive array for a larger size and then copies the old array to it.
Alain O'Dea
+7  A: 

Unless you have a strong reason otherwise, I'd recommend using Lists over arrays.

There are some specific cases where you will want to use an array (e.g. when you are implementing your own data structures, or when you are addressing a very specific performance requirement that you have profiled and identified as a bottleneck) but for general purposes Lists are more convenient and will offer you more flexibility in how you use them.

Where you are able to, I'd also recommend programming to the abstraction (List) rather than the concrete type (ArrayList). Again, this offers you flexibility if you decide to chenge the implementation details in the future.

To address your readability point: if you have a complex structure (e.g. ArrayList of HashMaps of ArrayLists) then consider either encapsulating this complexity within a class and/or creating some very clearly named functions to manipulate the structure.

mikera
+1  A: 

The List is more powerful:

  • You can resize the list after it has been created.
  • You can create a read-only view onto the data.
  • It can be easily combined with other collections, like Set or Map.

The array works on a lower level:

  • Its content can always be changed.
  • Its length can never be changed.
  • It uses less memory.
  • You can have arrays of primitive data types.
Roland Illig
It uses _vastly_ less memory for primitives, and the memory wasted by Collections is just silly...
Vuntic
Just to clarify: By *silly*, do you mean "the Collections use more memory than necessary" or do you mean "it's silly to even mention the difference between Collections and arrays, because it's negligible"?
Roland Illig
+2  A: 

Choose a data structure implementation and interface based on primary usage:

  • Random Access: use List for variable type and ArrayList under the hood

  • Appending: use Collection for variable type and LinkedList under the hood

  • Loop and process: use Iterable and see the above for use under the hood based on producer code

Use the most abstract interface possible when handing around data. That said don't use Collection when you need random access. List has get(int) which is very useful when random access is needed.

Typed collections like List<String> make up for the syntactical convenience of arrays.

Don't use Arrays unless you have a qualified performance expert analyze and recommend them. Even then you should get a second opinion. Arrays are generally a premature optimization and should be avoided.

Generally speaking you are far better off using an interface rather than a concrete type. The concrete type makes it hard to rework the internals of the function in question. For example if you return int[][] you have to do all of the computation upfront. If you return List> you can lazily do computation during iteration (or even concurrently in the background) if it is beneficial.

Alain O'Dea
+1  A: 

I wanted to point out that Lists can hold the wrappers for the primitive data types that would otherwise need to be stored in an array. (ie a class Double that has only one field: a double) The newer versions of Java convert to and from these wrappers implicitly, at least most of the time, so the ability to put primitives in your Lists should not be a consideration for the vast majority of use cases.

For completeness: the only time that I have seen Java fail to implicitly convert from a primitive wrapper was when those wrappers were composed in a higher order structure: It could not convert a Double[] into a double[].

Aviendha