Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API java 5 and more: should I return an array or a Collection?

In the spirit of Best Practices: Always return a ____, never a ____, I face a similar question in my upcoming migration from JDK1.4.2 to JDK5 and more. (Yes, I know, JDK1.4.2 is EOL! ;-) ).

For functions returning a collection (which are not simple property collections), I always prefer (in JDK1.4.2) returning an Array instead of a generic List, because:

  • it enforces the returning type (MyObject[] instead of List of Objects, much more type-safe on a static -- as in 'compilation' -- level)
  • it suggests a 'read-only' character to the returned collection (it is more complicated to add an element to the collection, even though this is not as rigorous as the 'read-only' keyword in c#). This is not the same as saying it is 'immutable' since the references inside the array can still be modified...

Of course, I do always create this returned array (I do not expose any 'internal' array)

Now, In JDK5 and more, I could use List<MyObject> if I want to.

What are the good reasons for choosing to return MyObject[] instead of List or Collection<MyObject> when coding in java5 ?

Bonus, if Collection<MyObject> is used, is it possible to:

  • enforce a read-only attribute on the returned collection ? (no add() or remove() possible)
  • enforce an immutable aspect to the returned collection ? (even the references of that collection can not be modified)

PS: The JavaGenericFAQ did not quite have that one.

like image 632
VonC Avatar asked Oct 22 '08 12:10

VonC


People also ask

Which is better array or collection in Java?

Arrays due to fast execution consumes more memory and has better performance. Collections, on the other hand, consume less memory but also have low performance as compared to Arrays. Arrays can hold the only the same type of data in its collection i.e only homogeneous data types elements are allowed in case of arrays.

Should I use collection or list Java?

It depends on what guarantees you want to provide the user. If the data is sequential such that the order of the elements matter and you are allowing duplicates, then use a list. If order of elements does not matter and duplicates may or may not be allowed, then use a collection.

When would it be appropriate to use arrays in Java?

Arrays are used to store multiple values in a single variable, instead of declaring separate variables for each value.

Are arrays more efficient than lists Java?

Conclusion: set operations on arrays are about 40% faster than on lists, but, as for get, each set operation takes a few nanoseconds - so for the difference to reach 1 second, one would need to set items in the list/array hundreds of millions of times!


2 Answers

Prefer Collection (or List, or Set as appropriate) to an array. With generics you get the type-checking that was lacking pre-Java 5. Also, by exposing only the interface, you are free to change the implementation later (e.g. switch an ArrayList for a LinkedList).

Arrays and generics don't mix very well. So, if you want to take advantage of generics, you should usually avoid arrays.
I.e: You can't generically create an array. For example, if T is a generic type then "new T[0]" doesn't compile. You'd have to do something like "(T[]) new Object[0]", which generates an unchecked cast warning. For the same reason, you can't use generic types with varargs without warnings.

Using Collections.unmodifiableCollection (and similar methods), you get the read-only constraint (which you can't achieve with an array - you would have to return a clone of the array).

You can't enforce immutability of members, but then you can't do that with an array either.

like image 160
Dan Dyer Avatar answered Oct 18 '22 19:10

Dan Dyer


Actually arrays still have one advantage over Collections/Lists. Due to the way that Java implements Generics through type erasure, you cannot have two methods that take Collections as arguments yet only differ by the Collection's generic type.

Ex:

public void doSomething(Collection<String> strs) { ... } public void doSomething(Collection<Integer> ints) { ... } 

The two above methods will not compile because the javac compiler uses type erasure and thus cannot pass the type information to the JVM. The JVM will only see two methods that take a Collection as its argument.

In the above cases, the best work-around is to make the methods take arrays as their arguments and use the Collection/List's toArray() method when passing the arguments to them. If you still want to use Collection/List's inside the above methods, just use java.util.Arrays.asList() method to get your List back.

Ex:

public void doSomething(String[] strs) {         List<String> strList = Arrays.asList(strs);         ... }  public void doSomething(Integer[] ints) {         List<Integer> intList = Arrays.asList(ints);         ... }  public static void main(String[] args) {         List<String> strs = new ArrayList<String>();         List<Integer> ints = new ArrayList<Integer>();         obj.doSomething(strs.toArray());         obj.doSomething(ints.toArray()); } 
like image 31
mcjabberz Avatar answered Oct 18 '22 17:10

mcjabberz