What is the use of adding a null key or value to a HashMap in Java?

103,518

Solution 1

I'm not positive what you're asking, but if you're looking for an example of when one would want to use a null key, I use them often in maps to represent the default case (i.e. the value that should be used if a given key isn't present):

Map<A, B> foo;
A search;
B val = foo.containsKey(search) ? foo.get(search) : foo.get(null);

HashMap handles null keys specially (since it can't call .hashCode() on a null object), but null values aren't anything special, they're stored in the map like anything else

Solution 2

One example would be for modeling trees. If you are using a HashMap to represent a tree structure, where the key is the parent and the value is list of children, then the values for the null key would be the root nodes.

Solution 3

One example of usage for null values is when using a HashMap as a cache for results of an expensive operation (such as a call to an external web service) which may return null.

Putting a null value in the map then allows you to distinguish between the case where the operation has not been performed for a given key (cache.containsKey(someKey) returns false), and where the operation has been performed but returned a null value (cache.containsKey(someKey) returns true, cache.get(someKey) returns null).

Without null values, you would have to either put some special value in the cache to indicate a null response, or simply not cache that response at all and perform the operation every time.

Solution 4

The answers so far only consider the worth of have a null key, but the question also asks about any number of null values.

The benefit of storing the value null against a key in a HashMap is the same as in databases, etc - you can record a distinction between having a value that is empty (e.g. string ""), and not having a value at all (null).

Solution 5

Here's my only-somewhat-contrived example of a case where the null key can be useful:

public class Timer {
    private static final Logger LOG = Logger.getLogger(Timer.class);
    private static final Map<String, Long> START_TIMES = new HashMap<String, Long>();

    public static synchronized void start() {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(null)) {
            LOG.warn("Anonymous timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(null).longValue()) +"ms"); 
        }
        START_TIMES.put(null, now);
    }

    public static synchronized long stop() {
        if (! START_TIMES.containsKey(null)) {
            return 0;
        }

        return printTimer("Anonymous", START_TIMES.remove(null), System.currentTimeMillis());
    }

    public static synchronized void start(String name) {
        long now = System.currentTimeMillis();
        if (START_TIMES.containsKey(name)) {
            LOG.warn(name + " timer was started twice without being stopped; previous timer has run for " + (now - START_TIMES.get(name).longValue()) +"ms"); 
        }
        START_TIMES.put(name, now);
    }

    public static synchronized long stop(String name) {
        if (! START_TIMES.containsKey(name)) {
            return 0;
        }

        return printTimer(name, START_TIMES.remove(name), System.currentTimeMillis());
    }

    private static long printTimer(String name, long start, long end) {
        LOG.info(name + " timer ran for " + (end - start) + "ms");
        return end - start;
    }
}
Share:
103,518
subhashis
Author by

subhashis

Updated on July 08, 2022

Comments

  • subhashis
    subhashis almost 2 years

    HashMap allows one null key and any number of null values. What is the use of it?

  • Pacerier
    Pacerier about 12 years
    So if .hashCode() is not possible on null who decides which carriage the null key will enter?
  • Michael Mrozek
    Michael Mrozek about 12 years
    @Pacerier There's a special method in HashMap (putForNullKey) that handles it; it stores it in table 0
  • Nic
    Nic over 8 years
    If you're trying to stop a nonexistent timer, or one that's been stopped already, that should be an error, not ignored.
  • aroth
    aroth over 8 years
    @QPaysTaxes - Depends on your intent. If you want a lightweight utility that can be easily used, you generally don't want to throw Exception's around. Besides, it's not like attempting to stop a non-existent or already-stopped timer is something that the caller can generally recover from.
  • dheerajraaj
    dheerajraaj almost 7 years
    @MichaelMrozek your last line B val = foo.containsKey(search) ? foo.get(search) : foo.get(null); I think we can simply call get method on search key which will have same result. B val = foo.get(search); could you please correct me if I am getting something wrong?
  • Michael Mrozek
    Michael Mrozek almost 7 years
    @dheeraj92 Your code will set val to null if the key doesn't exist; mine sets it to whatever null maps to in the map. That was the point, I store a default non-null value at the null key in the map and use it if the actual key doesn't exist