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 TreeMultimap
, but I can't use it because the value type doesn't implement Comparable
.
public class MyObject /* doesn't implement Comparable */ {
private String name;
private int score;
// Getters/setters are implemented
public static Function<MyObject,Integer> myObjectToScore {
@Override public Integer apply (MyObject o) { return o.score; }
}
public static Multimap<Integer,MyObject> indexOnScore(Iterable<MyObject> i) {
Multimap<Integer,MyObject> m = Multimaps.index(i, myObjectToScore());
// Do the sort of the keys.
return m;
}
}
I've thought about getting a SortedSet
of the keys, then iterating over each of these keys in the sorted set to fetch the various values, but I was hoping using an existing (yet undiscovered) feature in Guava rather than using this kind of hack.
Note: I won't make MyObject
implement Comparable
because it makes no sense with my actual object.
Example of input/output:
Set<MyObject> s = Sets.newHashSet(
new MyObject("a", 2),
new MyObject("b", 3),
new MyObject("c", 1),
new MyObject("d", 3),
new MyObject("e", 1)
); // Assuming constructor MyObject(String name, int score)
for (Map.Entry<Integer, MyObject> e: MyObject.indexedOnScore(s).entries()) {
System.out.printf("%d -> %s%n", e.getKey(), e.getValue().getName());
}
Prints:
1 -> c // or switched with line below
1 -> e
2 -> a
3 -> b // or switched with line below
3 -> d
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.