Collections framework idioms

Java's Collections Framework provides many convenient idioms for accomplishing common tasks (e.g., removing a collection's null elements). In this post, I present a handful of these idioms, which can help you write clearer and shorter code.

Easy list creation

Q: What's the easiest way to create a list?

A: The easiest way to create a list is to use the java.util.Arrays class's <T> List<T> asList(T... a) generic class method, which returns a fixed-size list backed by the specified array. For example, the following code fragment creates a list of inner planet names:

List<String> innerPlanetNames = Arrays.asList("Mercury", 
                                              "Venus", 
                                              "Earth", 
                                              "Mars");

From collection to array

Q: How do I copy a collection's elements to an array?

A: The Collection interface declares the following pair of methods for copying a collection's elements to an array:

  • Object[] toArray(): Return a new array containing all of this collection's elements.
  • <T> T[] toArray(T[] a): Return the specified array or a new array (when a is too small to hold all of the elements) containing all of this collection's elements. Because this method is generic, you don't need to use a cast operator, which you have to use with the former method unless the target array has java.lang.Object type.

The following code fragment uses the second method to copy the previously created innerPlanetNames list to a new array:

String[] _innerPlanetNames =
   innerPlanetNames.toArray(new String[0]);

Null element removal

Q: How do I remove a collection's null elements?

A: Assuming that c is of type java.util.Collection, execute the following expression to remove a collection's null elements:

c.removeAll(Collections.singleton(null));

The Collections.singleton(null) expression returns an immutable set consisting of a single null reference. This set is passed as an argument to Collection's boolean removeAll(Collection<?> c) method, which removes all of this collection's elements that are also contained in the specified collection (c). In this case, all null elements are removed. This method returns true when this collection is changed as a result of the call; otherwise, false returns.

Because removeAll() is an optional operation, this method throws java.lang.UnsupportedOperationException when it's not supported by a class that implements the Collection interface. For example, because asList() returns a list based on an array, and because arrays don't support the addition or removal of elements, calling removeAll() on such a list results in UnsupportedOperationException being thrown.

Duplicate element removal

Q: How do I remove a list's duplicate elements?

A: To remove a list's duplicate elements, pass it to a java.util.HashSet instance (when you don't care about the resulting order) or a java.util.LinkedHashSet instance (when order matters). Consider the following code fragment:

List<String> names = Arrays.asList("John", "Jane", "Tom", "Jane", "Tom",
                                   "Brian");
System.out.println(names);                      // Output: [John, Jane, Tom, Jane, Tom, Brian]
System.out.println(new HashSet<>(names));       // Output: [Brian, Jane, Tom, John]
System.out.println(new LinkedHashSet<>(names)); // Output: [John, Jane, Tom, Brian]

Map entry iteration

Q: How do I iterate over a map's entries?

A: To iterate over a map's entries, employ the following idiom:

for (Map.Entry<<i>KeyType</i>, <i>ValueType</i>> e: m.entrySet())
   System.out.println(e.getKey()+": "+e.getValue());

This idiom invokes java.util.Map's Set<Map.Entry<K,V>> entrySet() method to return a java.util.Set view of the mappings contained in this map. Each mapping is represented by an object whose class implements Map's nested Entry<K,V> interface, whose K getKey() method returns the key and V getValue() method returns the value.

The follow code fragment offers a more concrete example:

Map<String, String> capitals = new TreeMap<>();
capitals.put("United States", "Washington");
capitals.put("Russia", "Moscow");
capitals.put("England", "London");
capitals.put("France", "Paris");
for (Map.Entry<String, String> entry: capitals.entrySet())
   System.out.println(entry.getKey()+": "+entry.getValue());

What's next?

Next time, I focus on Java's transient keyword. I discuss this keyword's purpose, show how to use transient, and discuss this keyword in the context of class fields.

download
Get the source code for this post's applications. Created by Jeff Friesen for JavaWorld

The following software was used to develop the post's code:

  • 64-bit JDK 7u6

The post's code was tested on the following platform(s):

  • JVM on 64-bit Windows 7 SP1
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.