Sunday, 13 March 2011

Convenience Implementations

This section describes several mini-implementations that can be more convenient and more efficient then the general purpose implementations when you don't need the full power of a general purpose implementation. All of the implementations in this section are made available via static factory methods or exported constants, rather than public classes.

List-view of an Array

The Arrays.asList(in the API reference documentation)method returns a List-view of its array argument. Changes to the List write through to the array and vice-versa. The size of the collection is that of the array, and cannot be changed. If the add or remove method is called on the List, an UnsupportedOperationException will result. The normal use of this implementation is as a bridge between array-based and collection-based APIs. It allows you to pass an array to a method expecting a Collection or a List. However, this implementation has another use. If you need a fixed-size List, it's more efficient than any general-purpose List implementation. Here's the idiom:
List l = Arrays.asList(new Object[size]);
Note that a reference to the backing array is not retained.

Immutable Multiple-Copy List

Occasionally you'll need an immutable List consisting of multiple copies of the same element. The Collections.nCopies(in the API reference documentation)method returns such a List. This implementation has two main uses. The first is to initialize a newly created List. For example, suppose you want an ArrayList initially consisting of 1000 null elements. The following incantation does the trick:
List l = new ArrayList(Collections.nCopies(1000, null));
Of course, the initial value of each element needn't be null. The second main use is to grow an existing List. For example, suppose you want to add 69 copies of the string fruit bat to the end of a List. It' not clear why you'd want to do such a thing, but let's just suppose you did. Here's how you'd do it:
lovablePets.addAll(Collections.nCopies(69, "fruit bat"));
By using the form of addAll that takes an index as well as a Collection, you can add the new elements to the middle of a List instead of at the end.

Immutable Singleton Set

Sometimes you'll need an immutable singleton Set, which consists of a single, specified element. The Collections.singleton(in the API reference documentation)method returns such a Set. One use of this implementation is this idiom to remove all occurrences of a specified element from a Collection:
c.removeAll(Collections.singleton(e));
There's a related idiom to remove from a Map all elements that map to a specified value. For example, suppose you have a Map, profession, that maps people to their line of work. Suppose you want to eliminate all of the lawyers. This one-liner will do the deed:
profession.values().removeAll(Collections.singleton(LAWYER));
One more use of this implementation is to provide a single input value to a method that is written to accept a Collection of values.

Empty Set and Empty List Constants

The Collections class provides two constants, representing the empty Set and the empty List, Collections.EMPTY_SET(in the API reference documentation)and Collections.EMPTY_LIST(in the API reference documentation). It's not clear that these constants really qualify as implementations, but this lesson seemed like as good a place to mention them as any. The main use of these constants is as input to methods that take a Collection of values, when you don't want to provide any values at all.

No comments:

Post a Comment