Choosing between Lists
The best approach is probably to choose an ArrayList as your default and to change to a LinkedList if you discover performance problems due to many insertions and removals from the middle of the list. And of course, if you are working with a fixed-sized group of elements, use an array.
Choosing between Sets
The performance of HashSet is generally superior to TreeSet for all operations (but in particular for addition and lookup, the two most important operations). The only reason TreeSet exists is because it maintains its elements in sorted order, so you use it only when you need a sorted Set.
Note that LinkedHashSet is slightly more expensive for insertions than HashSet; this is because of the extra cost of maintaining the linked list along with the hashed container. However, traversal is cheaper with LinkedHashSet because of the linked list.
As another example, a Set can be implemented as either a TreeSet, a HashSet, or a LinkedHashSet. Each of these have different behaviors: HashSet is for typical use and provides raw speed on lookup, LinkedHashSet keeps pairs in insertion order, and TreeSet is backed by TreeMap and is designed to produce a constantly sorted set. The idea is that you can choose the implementation based on the behavior you need. Most of the time, the HashSet is all that’s necessary and should be your default choice of Set.
Choosing between Maps
When choosing between implementations of Map, the size of the Map is what most strongly affects performance.
In the end, when you’re using a Map, your first choice should be HashMap, and only if you need a constantly sorted Map will you need TreeMap.
LinkedHashMap is slightly slower than HashMap because it maintains the linked list in addition to the hashed data structure. IdentityHashMap has different performance because it uses == rather than equals( ) for comparisons.
The TreeMap is generally slower than the HashMap, so why would you use it? As a way to create an ordered list. The behavior of a tree is such that it’s always in order and doesn’t have to be specially sorted. Once you fill a TreeMap, you can call keySet( ) to get a Set view of the keys, then toArray( ) to produce an array of those keys. You can then use the static method Arrays.binarySearch( ) (discussed later) to rapidly find objects in your sorted array. Of course, you would probably only do this if, for some reason, the behavior of a HashMap was unacceptable, since HashMap is designed to rapidly find things. Also, you can easily create a HashMap from a TreeMap with a single object creation.
Making a Collection or Map unmodifiable
Often it is convenient to create a read-only version of a Collection or Map. The Collections class allows you to do this by passing the original container into a method that hands back a read-only version. There are four variations on this method, one each for Collection (if you can’t treat a Collection as a more specific type), List, Set, and Map.
Calling the “unmodifiable” method for a particular type does not cause compile-time checking, but once the transformation has occurred, any calls to methods that modify the contents of a particular container will produce an UnsupportedOperationException.
In each case, you must fill the container with meaningful data before you make it read-only. Once it is loaded, the best approach is to replace the existing reference with the reference that is produced by the “unmodifiable” call. That way, you don’t run the risk of accidentally trying to change the contents once you’ve made it unmodifiable.
*************************************************************************************************************
On the other hand, this tool also allows you to keep a modifiable container as private within a class and to return a read-only reference to that container from a method call. So, you can change it from within the class, but everyone else can only read it.
**************************************************************************************************************
Methods in Collections :
public static Collection unmodifiableCollection(Collection c)
public static Set unmodifiableSet(Set s)
public static SortedSet unmodifiableSortedSet(SortedSet s)
public static List unmodifiableList(List list)
public static Map unmodifiableMap(Map m)
public static SortedMap unmodifiableSortedMap(SortedMap m)
================================================================================
Summary
To review the containers provided in the standard Java library:
I. An array associates numerical indices to objects. It holds objects of a known type so that you don’t have to cast the result when you’re looking up an object. It can be multidimensional, and it can hold primitives. However, its size cannot be changed once you create it.
II. A Collection holds single elements, and a Map holds associated pairs.
III. Like an array, a List also associates numerical indices to objects—you can think of arrays and Lists as ordered containers. The List automatically resizes itself as you add more elements. But a List can hold only Object references, so it won’t hold primitives, and you must always cast the result when you pull an Object reference out of a container.
IV. Use an ArrayList if you’re doing a lot of random accesses, but a LinkedList if you will be doing a lot of insertions and removals in the middle of the list.
V. The behavior of queues, deques, and stacks is provided via the LinkedList.
VI. A Map is a way to associate not numbers, but objects with other objects. The design of a HashMap is focused on rapid access, whereas a TreeMap keeps its keys in sorted order, and thus is not as fast as a HashMap. A LinkedHashMap keeps its elements in insertion order, but may also reorder them with its LRU algorithm.
VII. A Set only accepts one of each type of object. HashSets provide maximally fast lookups, whereas TreeSets keep the elements in sorted order. LinkedHashSets keep elements in insertion order.
VIII. There’s no need to use the legacy classes Vector, Hashtable, and Stack in new code.