Search code examples
javaguavamultimap

Editable multimap index


I am having hard time looking for constructor to build mutable Multimap. My code is:

Multimap<String, DbEntity> multimapByKey = Multimaps.index(goodHosts, instanceGetKeyfunction);

...

multimapByKey.removeAll(someKey); 
// throws 
// java.lang.UnsupportedOperationException
//     at com.google.common.collect.ImmutableListMultimap.removeAll(Unknown Source)
//     at com.google.common.collect.ImmutableListMultimap.removeAll(Unknown Source)

Since index returns ImmutableListMultimap I really cannot modify it. However, I cannot see other options to do group by keyFunction for Multimaps on the official documentation.


Solution

  • You can create a method that return a mutable Multimap, like the index function, like this:

    public static <K, V> Multimap<K, V> indexMutable(Iterable<V> values,
            Function<? super V, K> function) {
    
        // check null value, function
        Multimap<K, V> map = ArrayListMultimap.create();
    
        for (V v : values) {
            // check null V
            map.put(function.apply(v), v);
        }
    
        return map;
    }
    

    And use like this:

    @Test
    public void testMutableMap() throws Exception {
    
        List<String> badGuys = Arrays.asList("Inky", "Blinky", "Pinky",
                "Pinky", "Clyde");
        Function<String, Integer> stringLengthFunction = new Function<String, Integer>() {
    
            public Integer apply(String input) {
                return input.length();
            }
        };
    
        Multimap<Integer, String> multipmap = indexMutable(badGuys,
                stringLengthFunction);
    
        System.out.println(multipmap);
        multipmap.clear();
        System.out.println("It's mutable!");
    
        for (String guy : badGuys) {
            multipmap.get(stringLengthFunction.apply(guy)).add(guy);
        }
    
        System.out.println(multipmap);
    }
    

    It's output:

    {4=[Inky], 5=[Pinky, Pinky, Clyde], 6=[Blinky]}
    It's mutable!
    {4=[Inky], 5=[Pinky, Pinky, Clyde], 6=[Blinky]}
    

    This example, is the same for the Javadoc of Multimaps#index.