I would like to have a c.g.c.c.Multimap
that is sorted based on keys only. The values shouldn\'t be sorted. I\'ve tried to build something with guava\'s T
Multimaps.index
returns an ImmutableListMultimap
, so you wouldn't be able to sort it after creating it. You could, however, first create a sorted copy of your Iterable<MyObject>
and feed that to Multimap.index
... ImmutableListMultimap
keeps things in the same order it was given them.
public static ImmutableMultimap<Integer, MyObject> indexOnScore(Iterable<MyObject> i) {
List<MyObject> sorted = Ordering.natural().onResultOf(myObjectToScore())
.sortedCopy(i);
return Multimaps.index(sorted, myObjectToScore());
}
Another option might be to create a TreeMultimap
and use Ordering.arbitrary()
as the Comparator
for the values.
Best solution which always works for me is to use Multimap & TreeMultiMap. this will order results in ascending order on keys even if you have multiple duplicate keys. Solution below:
Multimap<Double, Integer> map= TreeMultimap.create(Ordering.natural().reverse(), Ordering.natural());
if (!map.isEmpty()) {
printMap(map);
}
public static <K, V> void printMap(Multimap<Double, Integer> map) throws Exception {
for (Map.Entry<Double, Integer> entry : map.entries()) {
System.out.println("Key : " + entry.getKey()
+ " Value : " + entry.getValue());
}
}
Call Multimaps.newMultimap, which gives you the flexibility to create, for example, a Multimap backed by TreeMap whose values are ArrayLists.
I'd like to point out that the alternative proposed solution, namely "to create a TreeMultimap and use Ordering.arbitrary() as the Comparator for the values", only works if MyObject doesn't override equals() or hashcode(). Ordering.arbitrary() is inconsistent with equals and uses object identity instead, which makes it not a good idea to use it in conjunction with a TreeSet.
Though the OP's specific situation seems to have been answered using immutable multimap building functions, I needed a mutable version of what he was asking for. In case it helps anyone, here's the generic method I ended up creating:
static <K, V> Multimap<K, V> newTreeArrayListMultimap(
final int expectedValuesPerKey)
{
return Multimaps.newMultimap(new TreeMap<K, Collection<V>>(),
new Supplier<Collection<V>>()
{
@Override
public Collection<V> get()
{
return new ArrayList<V>(expectedValuesPerKey);
}
});
}
MultimapBuilder was introduced in Guava 16:
<K extends Comparable<? super K>, V> ListMultimap<K, V> multimap() {
return MultimapBuilder.treeKeys().linkedListValues().build();
}
That keeps your keys sorted by their natural order (MultimapBuilder::treeKeys
is also overloaded to accept a custom comparator), and the values associated with each key are maintained in a LinkedList
(ArrayList
and HashSet
are among the other options).