Storing Objects in Java
Part 4 - The Collections class

by Thomas Paul

In this last column in our series, we are going to look at an important class to support the use of Collections
and Maps. The Collections class contains static methods designed to assist you in your use of your Collection objects.
The class itself has a private constructor, so it can't be instantiated or extended. All the methods of the class
are static. What kinds of methods are included? Let's take a look.

Sorting

The Collections class contains two methods you can use to sort a List. As we discussed in Part 2 of this series,
sorting can be done by having all the Objects to be sorted implement the compareTo( ) method or by passing in a
Comparator object to control sorting. The sort actually works by extracting an array from the List and then running
the Arrays.sort( ) method.

Here are the two sort methods:

void sort(List list) - Sorts the List using the compareTo( ) method of the objects in the List.

Searching

Once you have sorted your List, you can run a binary search against it when you need to locate an item in the
List. This will be much more efficient than iterating through the List to find an entry.
The results are undefined if you use a binary search on a List that is not sorted. The binarySearch( ) methods will
return the index of the found entry. If it isn't found, the methods will return a negative number which if made
positive would represent where in the List this item should be inserted to maintain sort order.

If you need to find that max or min elements in a Collection, there are methods for that also. The Collection
doesn't need to be sorted to run these methods.

Here are the max/min methods:

Object max(Collection coll)

Object max(Collection coll, Comparator comp)

Object min(Collection coll)

Object min(Collection coll, Comparator comp)

Synchronization

All of the Collection objects can be made thread-safe by using one of the synchronization methods. Two things
should be noted:

All operations against the Collection or Map must be done through the returned synchronized object and not
the object passed into the synchronization method.

Although all operations against the synchronized object are thread-safe, operations against the iterator of
these objects are not. When iterating over the Collection or Map, you must synchronize the block of code on the
synchronized object. Here is an example:

Creating Unmodifiable Collections

There may be times when you want to pass a Collection or Map to another class but you want to insure that the
object you pass is not changed. You can do this by passing an unmodifiable Collection or Map. The Collections class
provides methods to create an unmodifiable view of a Collection or Map. This view is not a copy of the original
object but simply passes through all methods that don't change the contents of the object. All other methods will
throw an UnsupportedMethodException. This limitation is true for the object itself, any iterators created
from the object, as well as any Collections created (in the case of a Map).

Here are the methods to create unmodifiable objects:

Collection unmodifiableCollection(Collection c)

List unmodifiableList(List l)

Map unmodifiableMap(Map m)

Set unmodifiableSet(Set s)

SortedMap unmodifiableSortedMap(SortedMap s)

SortedSet unmodifiableSortedSet(SortedSet s)

Creating Singleton Collections

There may be times when you want to pass a single object to a method that requires a Collection as an input
parameter. You can do this by creating a singleton Collection. The singleton methods construct a Collection or
Map out of the Object parameters that you pass to the method.

Here are the singleton methods:

Collection singleton(Object o)

List singeltonList(Object o)

Map singletonMap(Object key, Object value)

Other Odds and Ends

The Collections class has several other methods which may be useful under certain circumstances. Need to randomize
the items in your list? Try one of the shuffle( ) methods. Or you can reverse the order of your List with
the reverse( ) method or rotate items within the List using the rotate( ) method. Or you can use
the enumeration( ) method to create an Enumeration from your Collection. Or use the list( ) method
to create an ArrayList from your Enumeration. Need to fill a List with the same Object? There's the fill( )
method. Need to create a List containing the same Object n times? Try the nCopies() method.
You can replace one Object in a List with another Object using replaceAll( ) or swap the position of two
Objects in a List using the swap( ) method.

One last property of the Collections class is sometimes useful. Do you need to pass an empty List, Map, or Set
to a method? Don't bother creating one. As long as the method won't attempt to modify the Object, you can use Collections.EMPTY_LIST,
Collections.EMPTY_MAP, or Collections.EMPTY_SET.

Conclusion

The Collections class contains some useful (and some unusual) methods to help us work with Collection and Map
objects. If you ever need any of the functionality it provides, the Collections class can save you some trouble
and speed up your development.

That is the end of our four part series on Collections and Maps. I hope you found the information in this series
useful.