Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort Guava Multimap by number of values

Tags:

java

guava

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")?

like image 406
Jeff Olson Avatar asked Oct 24 '11 20:10

Jeff Olson


1 Answers

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);
    }
}
like image 142
JB Nizet Avatar answered Sep 22 '22 11:09

JB Nizet