Search code examples
javaguava

Sort Guava Multimap by number of values


If I have a Guava Multimap, how would I sort the entries based on the number of values for the given key?

For instance:

Multimap<String, String> multiMap = ArrayListMultimap.create();
multiMap.put("foo", "1");
multiMap.put("bar", "2");
multiMap.put("bar", "3");
multiMap.put("bar", "99");

Given this, when iterating over multiMap, how would I get the "bar" entries to come first (since "bar" has 3 values vs. only 1 for "foo")?


Solution

  • Extract the entries in a list, then sort the list :

    List<Map.Entry<String, String>> entries = new ArrayList<Map.Entry<String, String>>(map.entries());
    Collections.sort(entries, new Comparator<Map.Entry<String, String>>() {
        @Override
        public int compare(Map.Entry<String, String> e1, Map.Entry<String, String> e2) {
            return Ints.compare(map.get(e2.getKey()).size(), map.get(e1.getKey()).size());
        }
    });
    

    Then iterate over the entries.

    Edit :

    If what you want is in fact iterate over the entries of the inner map (Entry<String, Collection<String>>), then do the following :

    List<Map.Entry<String, Collection<String>>> entries = 
        new ArrayList<Map.Entry<String, Collection<String>>>(map.asMap().entrySet());
    Collections.sort(entries, new Comparator<Map.Entry<String, Collection<String>>>() {
        @Override
        public int compare(Map.Entry<String, Collection<String>> e1, 
                           Map.Entry<String, Collection<String>> e2) {
            return Ints.compare(e2.getValue().size(), e1.getValue().size());
        }
    });
    
    // and now iterate
    for (Map.Entry<String, Collection<String>> entry : entries) {
        System.out.println("Key = " + entry.getKey());
        for (String value : entry.getValue()) {
            System.out.println("    Value = " + value);
        }
    }