We are learning about the Collection Interface and I was wondering if you all have any good advice for it's general use? What can you do with an Collection that you cannot do with an array? What can you do with an array that you cannot do with a Collection(besides allowing duplicates)?
-
2Collections allows duplicate. – Rudy May 23 '11 at 16:31
-
Collections can (sometimes) contain duplicates based on their type. Sets can't, but lists can for example. It all depends on the (more specific) collection type. – Michael Berry May 23 '11 at 16:32
-
@kreeSeeker: by "array" I take you mean a primitive array, like an *int[]* (seen that, say, an *ArrayList* is itself extending *Collection* at one point in its monstrously huge inheritance hierarchy). Well, what you can do with, say, an int[], that you cannot do with an *List{Integer}* is get the most out of your hardware which is important for people doing, for example, number crunching (and, yes, Java can and *is* used to crunch numbers, just not with the default collection). People don't realize that amount of waste that goes in *Map{Integer,Integer}*... Besides those using Trove ;) – SyntaxT3rr0r May 23 '11 at 16:33
-
4@Marcelo Hernández Rishmawy: *"Google is your friend"* is not the kind of answer/comment welcome on SO. And hiding it behind a *tinyurl* is lame. SO is a place to find answers, not links to search engines. – SyntaxT3rr0r May 23 '11 at 16:34
-
2@Rudy, @Berry120, @SyntaxT3rr0r, even answers to extremely simple questions should be **answers** and not comments. – Kirk Woll May 23 '11 at 16:35
-
@SyntaxT3rr0r Yes That is exactly what I meant – kreeSeeker May 23 '11 at 16:36
-
@SyntaxT3rr0r NUMBER Crunching! That was one of the things I have been looking for. – kreeSeeker May 23 '11 at 16:38
-
@Kirk Woll - my comment wasn't really an answer to the question at all though, it's just correcting a mistaken assumption that was mentioned in the last part of the question... – Michael Berry May 23 '11 at 16:39
-
@SyntaxT3rr0r Yes, I was probably mean and not helpful. But I think the question is neither specific, nor was a proper research made, and a little more effort from the asker would have meant a lot more effort from me and other people wanting to help. – Marcelo May 23 '11 at 16:43
5 Answers
The easy way to think of it is: Collections beat object arrays in basically every single way. Consider:
- A collection can be mutable or immutable. A nonempty array must always be mutable.
- A collection can allow or disallow null elements. An array must always permit null elements.
- A collection can be thread-safe; even concurrent. An array is never safe to publish to multiple threads.
- A list or set's
equals
,hashCode
andtoString
methods do what users expect; on an array they are a common source of bugs. - A collection is type-safe; an array is not. Because arrays "fake" covariance,
ArrayStoreException
can result at runtime. - A collection can hold a non-reifiable type (e.g.
List<Class<? extends E>>
orList<Optional<T>>
). An array will generate a warning for this. - A collection can have views (unmodifiable, subList...). No such luck for an array.
- A collection has a full-fledged API; an array has only set-at-index, get-at-index, length and clone.
- Type-use annotations like
@Nullable
are very confusing with arrays. I promise you can't guess what@A String @B [] @C []
means. - Because of all the reasons above, third-party utility libraries should not bother adding much additional support for arrays, focusing only on collections, so you also have a network effect.
Object arrays will never be first-class citizens in Java APIs.
A couple of the reasons above are covered -- but in much greater detail -- in Effective Java, Third Edition, Item 28, from page 126.
So, why would you ever use object arrays?
- You're very tightly optimizing something
- You have to interact with an API that uses them and you can't fix it
- so convert to/from a
List
as close to that API as you can
- so convert to/from a
- Because varargs (but varargs is overused)
- so ... same as previous
- Obviously some collection implementations must be using them
- I can't think of any other reasons, they suck bad

- 40,336
- 12
- 74
- 87
-
2From what I understand, arrays are inherently threadsafe without locking in the scenario where different threads are accessing disjoint parts of the array. Most collections are either not threadsafe at all for any operations concurrent with any writes, even when the regions being acted upon are disjoint, or else they impose substantial threading-related overhead even when all threads happen to access disjoint regions. In .net arrays can offer thread-safety even when threads use shared elements, via `Interlocked.CompareExchange` but I don't think that's available on Java array elements. – supercat Sep 22 '12 at 17:37
-
It's basically a question of the desired level of abstraction.
Most collections can be implemented in terms of arrays, but they provide many more methods on top of it for your convenience. Most collection implementations I know of for instance, can grow and shrink according to demand, or perform other "high-level" operations which basic arrays can't.
Suppose for instance that you're loading strings from a file. You don't know how many new-line characters the file contains, thus you don't know what size to use when allocating the array. Therefore an ArrayList is a better choice.

- 413,195
- 112
- 811
- 826
-
1while that is true for some of the collection classes, it's not true for all of them! Look at some of the implementations of BlockingQueues (in java.util.concurrent) which don't expand necessarily -- as for shrinking apart from LinkedList I am not aware of any that does that -- which ones are you refering to? – Liv May 23 '11 at 16:38
-
that's ok -- it might help occasionally if you include the names of some of the classes you are referring to (e.g. the ones which grow and the ones which shrink -- in fact I'm vary curious about that one as I only know of LinkedList to do so!). – Liv May 23 '11 at 16:42
-
obviously depends on how you define shrink. An ArrayLists size can shrink, while an arrays .length stays fixed, right? – aioobe May 23 '11 at 16:44
-
oh right, i'm with you! Obviously .size() can go up and down but the size of the array used internally never goes down -- I think that's the point I was trying to make. But I take your point! – Liv May 23 '11 at 17:00
The details are in the sub interfaces of Collection, like Set, List, and Map. Each of those types has semantics. A Set typically cannot contain duplicates, and has no notion of order (although some implementations do), following the mathematical concept of a Set. A List is closest to an Array. A Map has specific behavior for push and get. You push an object by its key, and you retrieve with the same key.
There are even more details in the implementations of each collection type. For example, any of the hash based collections (e.g. HashSet, HasMap) are based on the hashcode() method that exists on any Java object.
You could simulate the semantics of any collection type based of an array, but you would have to write a lot of code to do it. For example, to back a Map with an array, you would need to write a method that puts any object entered into your Map into a specific bucket in the array. You would need to handle duplicates. For an array simulating a Set, you would need to write code to not allow duplicates.

- 118,147
- 33
- 203
- 236
-
-
-
-
ArrayList's can grow and shrink. Arrays can't. That's one of the main differences between arrays and ArrayLists. (See my answer for details.) – aioobe May 23 '11 at 16:43
-
Ok I think I see it now. So what if the ArrayLists I mentioned were instead primitive Arrays? What would the above code do? – kreeSeeker May 23 '11 at 16:45
-
You can't do `addAll` on a primitive array. If you try to add elements past index `arr.length-1` you'll get an `ArrayIndexOutOfBoundsException`. – aioobe May 23 '11 at 16:48
-
@aioobe thats what I thought it would. So if you had two ArrayLists or LinkLists and wanted to combine them into the first List how could you use collections to do that? – kreeSeeker May 23 '11 at 16:51
-
the point is that the Collections have APIs that allow you to do things based on the type of the collection. An array is just an array. It has very little abstraction around it. – hvgotcodes May 23 '11 at 16:53
-
@hvgotcodes ok thanks. I have to go back to class. Thanks for All the Answers – kreeSeeker May 23 '11 at 16:57
The Collection interface is just a base interface for specialised collections -- I am not aware yet of a class that simply just implements Collection; instead classes implement specialized interfaces which extend Collection. These specialized interfaces and abstract classes provide functionality for working with sets (unique objects), growing arrays (e.g. ArrayList), key-value maps etc -- all of which you cannot do out of the box with an array. However, iterating through an array and setting/reading items from an array remains one of the fastest methods of dealing with data in Java.

- 6,006
- 1
- 22
- 29
One advantage is the Iterator interface. That is all Collections implement an Iterator. An Iterator is an object that knows how to iterate over the given collection and present the programmer with a uniformed interface regardless of the underlying implementation. That is, a linked list is traversed differently from a binary tree, but the iterator hides these differences from the programmer making it easier for the programmer to use one or the other collection.
This also leads to the ability to use various implementations of Collections interchangeably if the client code targets the Collection interface iteself.

- 102,349
- 23
- 137
- 192