Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing from guava (google) Multimap never removes the key itself. Why? How to do so?

I'm using the google collections library from guava, I believe the most recent version.

I find that once I remove the final (K, V) pair from the map for a given value of K, the map still contains an entry for K, where V is an empty collection.

I would rather have the map not contain this entry. Why can't I remove it? Or, if I can, how?

It's probably something simple that I have missed. Here is a code example. Thanks.

    // A plain ordinary map.
    Map<Integer, Integer> hm = new HashMap<Integer, Integer>();
    hm.put(1, 2);
    hm.remove(1);
    // Value of key 1 in HashMap: null
    System.out.println("Value of key 1 in HashMap: " + hm.get(1));

    // A list multimap.
    ListMultimap<Integer, Integer> lmm = ArrayListMultimap.<Integer, Integer> create();
    lmm.put(1, 2);
    lmm.remove(1, 2);
    // Value of key 1 in ArrayListMultiMap: []
    System.out.println("Value of key 1 in ArrayListMultiMap: " + lmm.get(1));

    // A set multimap.
    SetMultimap<Integer, Integer> smm = HashMultimap.<Integer, Integer> create();
    smm.put(1, 2);
    smm.remove(1, 2);
    // Value of key 1 in HashMultimap: []
    System.out.println("Value of key 1 in HashMultimap: " + smm.get(1));
like image 668
Puzzled Avatar asked May 28 '11 00:05

Puzzled


2 Answers

Actually when you remove the last value for a key in the multimap, the key is removed from the map. See for instance the behaviour of 'containsKey'

System.out.println("ListMultimap contains key 1? " + lmm.containsKey(1));

However when you get the values from the multimap, if there is no collection associated with the key, it will return an empty collection, see the implementation of get in AbstractMultimap:

/**
 * {@inheritDoc}
 *
 * <p>The returned collection is not serializable.
 */
@Override
public Collection<V> get(@Nullable K key) {
  Collection<V> collection = map.get(key);
  if (collection == null) {
    collection = createCollection(key);
  }
  return wrapCollection(key, collection);
}
like image 108
Hiery Nomus Avatar answered Oct 08 '22 17:10

Hiery Nomus


To totally remove the underlying entry from the Multimap, you need to use the Map view:

multimap.asMap().remove(key);
like image 20
Etienne Neveu Avatar answered Oct 08 '22 16:10

Etienne Neveu