91

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

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
subhashis
  • 4,629
  • 8
  • 37
  • 52

7 Answers7

126

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

Michael Mrozek
  • 169,610
  • 28
  • 168
  • 175
  • 4
    So if .hashCode() is not possible on null who decides which carriage the null key will enter? – Pacerier Feb 24 '12 at 17:08
  • 26
    @Pacerier There's a special method in `HashMap` (`putForNullKey`) that handles it; it stores it in table 0 – Michael Mrozek Feb 24 '12 at 17:39
  • 1
    @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? – dheerajraaj Jul 14 '17 at 20:30
  • 6
    @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 – Michael Mrozek Jul 14 '17 at 21:24
28

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.

Nic
  • 6,211
  • 10
  • 46
  • 69
tony
  • 301
  • 4
  • 7
6

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.

Theodore Murdock
  • 1,538
  • 1
  • 13
  • 28
Zorac
  • 339
  • 4
  • 7
3

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).

Eborbob
  • 1,905
  • 1
  • 15
  • 30
2

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;
    }
}
aroth
  • 54,026
  • 20
  • 135
  • 176
  • If you're trying to stop a nonexistent timer, or one that's been stopped already, that should be an error, not ignored. – Nic Dec 03 '15 at 03:15
  • @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. – aroth Dec 03 '15 at 03:29
1

Another example : I use it to group Data by date. But some data don't have date. I can group it with the header "NoDate"

Avinash
  • 6,064
  • 15
  • 62
  • 95
Anthone
  • 2,156
  • 21
  • 26
0

A null key can also be helpful when the map stores data for UI selections where the map key represents a bean field.

A corresponding null field value would for example be represented as "(please select)" in the UI selection.

Gunnar
  • 383
  • 4
  • 18