Paul Taylor
Paul Taylor

Reputation: 13110

Sort keys of multimap by highest value they contain

I using a Guava MultiMap (impl LinkedListMultimap) to allow me to store multiple values for a key, but then I want to sort the map by the highest value and return the keys.

i.e

After first run I have

key1:{13}
key2:{7}
key3:{11}

After second run I now have

key1:{13,14}
key2:{7,18}
key3:{11,1}

After third run I now have

key1:{13,14,16}
key2:{7,18,6}
key3:{11,1,22}

I want an order of

key3
key2
key1

and I want to output the keys (I dont need to know the values any longer)

I cant work out a way to do that, I dont have to use MultiMap it just looked like it might help

Upvotes: 3

Views: 1684

Answers (2)

iwein
iwein

Reputation: 26161

What I would do is stick the entrySet into a TreeSet with a custom comparator. Then pull out the keys.

sortedEntries = Sets.newTreeSet(comparator).addAll(multimap.entries());
return Collections2.transform(sortedEntries, keyExtractor);

The implementation of keyExtractor, comparator and parametrization is left as an exercise to the reader.

Upvotes: 2

Louis Wasserman
Louis Wasserman

Reputation: 198163

If I were you, I'd start by not using a Multimap, but rather, using a Map to track the greatest value associated with each key. Then, you have a Map<String, Integer>, and if you don't need to save the Map afterwards, then I'd do something like

final Map<String, Integer> map = ...
return Ordering.natural().onResultOf(Functions.forMap(map)).reverse()
          // a comparator to compare strings in descending order of their
          // associated values
       .immutableSortedCopy(map.keySet());

To unpack a bit:

Ordering.natural() // the natural ordering on integers
  .onResultOf(
     Functions.forMap(map) // use the Map<String, Integer> as a Function
     // this ordering now compares Strings by the natural ordering of
     // the integers they're mapped to
  .reverse(); // reverses the ordering, so it now sorts in descending order

Upvotes: 5

Related Questions