How to add null values to ConcurrentHashMap

Khawar Ali picture Khawar Ali · Jul 23, 2015 · Viewed 7.9k times · Source

I have a ConcurrentHashMap which is called from different threads to put values in it. I have to insert null values, but ConcurrentHashMap doesn't allow null values. Is there a way to do that or an alternate option to do this in Java?

Answer

dimo414 picture dimo414 · Jul 23, 2015

Rather than using null, which has no semantic meaning and is generally considered an antipattern, represent this "absent" notion as a concrete type that reflects your intent and forces callers to account for it properly.

A common solution is to use Optional (for pre-Java 8, use Guava's Optional) to represent the absence of a value.

So your map would have a type ConcurrentHashMap<Key, Optional<Value>>.


Another option is to represent whatever you intend to mean by null more directly in the type you're storing in the map, e.g. if null is supposed to mean "this used to exist, but no longer" you might create a class structure like so:

public abstract class Resource {
  public abstract void doSomething();
  public abstract ClosedResource close();
}

public class ActiveResource extends Resource {
  public void doSomething() { ... }
  public ClosedResource close() { ... }
}

public class ClosedResource extends Resource {
  public void doSomething() { /* nothing to do */ }
  public ClosedResource close() { return this; }
}

And then simply have a ConcurrentHashMap<Key, Resource>. There are pros and cons to both approaches depending on your exact needs, but both are objectively better than putting null values in your map.


You might also simply be able to avoid adding nulls at all - if you can't create a clear semantic meaning for null that's different from simply being absent (as suggested above), just use absence in the map to convey what you care about, rather than distinguishing between the absent and present-but-null cases.