Neil Walker
Neil Walker

Reputation: 6858

Guava null pointer on multimap with multiple null values

I'm using guava multimap (TreeMultiMap). I'm doing some unit tests to ensure it's ok but when I do the following test I get a null pointer exception from guava (I've cobbled together some code to recreate it). In the below just assume Location/Interconnect are simple classes. The natural order is by the id for the Location, i.e. 50, 51 in the code below.

Multimap<Location, Interconnect> interconnects;
interconnects = TreeMultimap.create();

Location l1 = new Location(50, "Test Location 1");
assertTrue(interconnects.put(l1, null));

Location l2 = new Location(51, "Test Location 2");
assertTrue(interconnects.put(l2, null));

//expect false but get null exception
assertFalse(locs.addLocation(l9));

I would have thought the last line being added would have returned simply false but it causes an exception.

If I change the null with a value they the second l9 returns false as I expected.

What's going wrong? All I could think of was Maps allow only one null key but this isn't a standard map and it isn't a key, it's the value.

The reason for testing this is I wish to allow adding of a Location without any values (as they may not be known) but then allow them to be added when they are known. I appreciate I can put in checks for duplicates with nulls but I want to know why it's failing in this scenario.

Upvotes: 1

Views: 1498

Answers (1)

Louis Wasserman
Louis Wasserman

Reputation: 198211

You're using a TreeMultimap, which means the values have to support the compareTo method. Trying to use compareTo on null values will throw a NullPointerException.

Except that when you add one value, there's no other value to compare it to, so compareTo isn't called until the second value, at which point everything falls over. TreeSet has similar issues, though they may have been fixed in more recent versions of Java.

Workarounds include using Ordering.natural().nullsFirst() or another null-accepting Comparator in the TreeMultimap, or using another Multimap implementation.

FWIW, Guava's Multimap is very much not designed to be used in the way you're using it, with a "Location without any values." You'd probably be better off falling back to the traditional Map<Key, Set<Value>>.

Upvotes: 4

Related Questions