Aug 10

The Collections Framework is an awesome way to represent may common types of data using the mathematical basis for sets. Sun has a great tutorial that explains what the framework is and how to use it. This is meant to be a simple guide (in the traditions of Effective Java) on how to use the framework correctly.

To make it clear at a glance, the good and bad code samples are marked in green and red respectively.

Collections have an isEmpty() method

The Collections framework goes out of its way to make the code reflect what you’re actually thinking. The proper way to check if a collection is empty is not to check if its size is zero. Use the isEmpty() method!

Avoid returning null to mean an empty collection

Leaving the possibility of returning a null instead of an empty collection makes your caller have to write extra boilerplate code to deal with that case. Most of the time an empty collection has the same meaning that a null would. Trying to use null to represent an error in whatever was supposed to generate the collection bypasses Java’s preferred way for handling errors: Exceptions.

Create an empty collection using Collections.empty***() methods

If you need an empty collection that’s guaranteed to stay empty (for example in your test code) use the Collections utility class to create them:

List myEmptyList = Collections.emptyList();
Set myEmptySet = Collections.emptySet();
Map myEmptyMap = Collections.emptyMap();

There are also constants for List.EMPTY_LIST, Set.EMPTY_SET, Map.EMPTY_MAP, but they’re best avoided since they do not support generics.

Iterate through collections using the foreach form when possible

You want the code to match your thought process as much as possible. Sometimes you can’t use the new foreach syntax introduced in Java 5 because you need access to the loop counter but in most cases the best way to iterate through a collection looks like this:

List foo;
for(String bar : foo) {
    System.out.println(bar);
}

The same foreach loop also works for arrays, with the exact same syntax.

Choosing which collection type to use

When you create a new data structure, don’t think of whether it’s a hash table, tree, whatever. Think about what the relationship of what you’re storing is. Is it a Collection, a Set, a Map, or a List?

If you’re not clear on what the difference is between a Collection, Map, Set, and a List check out the Javadocs (Sun’s Cliff’s notes). Start with what the requirements are for the data structure. Does it need to be ordered? Does it need to be unique? etc. Those will tell you which interface you need to use, and then you can decide what the underlying implementation should be. What if you use the wrong type of map/set/list and performance sucks? Well, then changing that implementation involves one line of code. And no one else needs to know or worry about it.

The left side is always an interface!

Like the title says, what you’re assigning to should almost never be an implementation. As a corollary, you should never return an implementation instead of an interface.

Instead of:

ArrayList foo = new ArrayList();
HashMap bar = new LinkedHashMap();

public TreeMap foo(){
…
}

do this:

List foo = new ArrayList();
Map bar = new LinkedHashMap();

public SortedMap foo(){
…
}

There might be a few exceptions to this rule, but they’re VERY rare. If you find yourself in one of those, stop and think really hard about whether you do actually need to break it. Better yet, ask the developer next to you about what she thinks.

If you’re explicitly casting, chances are something is wrong. Use generics.

Try to use generics on your collections. Knowing if foo is a list of Integers or Strings will make your client code much easier to read and will protect you from a lot of mistakes. Much more importantly, it will make it significantly easier for the next person who reads the code to understand what’s going on. If you find that you need a collection that needs to store multiple types of objects, then you should ask yourself whether you really have the right data structure and interface. Almost always the need to do that is a sign of a bad OO design.


4 comments so far...

  • Christopher Currie Said on August 14th, 2008 at 2:38 pm:

    If you’re not constrained to the Java Standard Library, I would prefer to use Google Collections “Immutable” collection objects, for empty collections or otherwise:

    List myEmptyList = com.google.common.collect.ImmutableList.of();
    List mySingleElementList = com.google.common.collect.ImmutableList.of(1);

    and so forth for the other collections. The one disadvantage is that it doesn’t return the same list every time, so you have less memory efficiency, but IMO the consistency of usage outweights this.

    Otherwise, good list!

  • Christopher Currie Said on August 14th, 2008 at 2:39 pm:

    Curse your non-HTML escaping comment forms, I did use generics in those examples!

  • betweenGo » Effective Java Collections Said on September 1st, 2008 at 2:54 pm:

    [...] thought this article, Effective Java Collections, was excellent. Here is the summary of the [...]

  • Websites tagged "oodesign" on Postsaver Said on September 17th, 2008 at 1:17 pm:

    [...] - Effective Java Collections saved by Lindaru2008-09-11 - Code reuse possibilities? saved by allenY2008-08-28 - Achieving Model [...]

leave a reply