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?
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 null
s 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.