Friday, December 02, 2011

Coding Tip of the Day: Using Map<?,?> Collections

I was working on some code in the last few days where I came across a protected Map map instance variable. I examined the code and javadocs which indicated that the intent was to provide a mapping of keys and values. However the actual implementation was setting the keys and values to the same value. This again is not really an issue. However, the usage of the Map was incorrect.

See if you can determine the issue from the code below.
The MapValueHolder<K,V> looks like the following. Here is the implementation.
As a general rule, you should use the key to fetch the value. Even if you expect that the values are the same. Since the instance variable is protected it can be modified in a sub-class, or any class in the same package. Since we code to interfaces, or abstractions (super classes). We can not be sure that the implementation class we are provided does what we expect. In this case, it does what we expect.
MapValueHolder Key --> A
MapValueHolder Key --> B
MapValueHolder Key --> C
A --> A
B --> B
C --> C

Here we continue using another implementation.

This time the result looks different.

MapValueHolder Key --> A
MapValueHolder Key --> B
MapValueHolder Key --> C
A --> null
B --> null
C --> null

This is because our MapValueHolder<K,V> is different.

Admittedly, the implementation above is a bit contrived. We really are getting is a Set<K>. In the next example, we get another result.

The result is considerably different.

MapValueHolder Key --> A
A --> A

Here is the implementation. Again, this is a contrived result where we are just returning the first key and value in a Map<K,V>. Here is another example which demonstrates unexpected results. This results in this very strange result.

Map --> {}

Here I use reflection to modify the expected result. If you have followed me to this point, you will have learned a little bit about the Java Type system, reflection, abstraction, and Collections. Yet, you may be asking what is the tip? Here are some rules:
  1. Use the keys to fetch values.
  2. Check for null values. In my examples, I did not check for null values.
  3. Use the correct Java Collection.
The Java Collection Framework covers most common cases. Take the time to read about them. The code above was based on a couple of issues I discovered: (1) Using keys for values, and (2) not using the correct collection. In this case, they should have used a List<V>. If they wanted to use an ordered Map<K,V>, they should have used a LinkedHashmap<K,V>

The code for the examples are here:

The code was developed using NetBeans 7.1 RC1.


Popular Posts