Reputation: 420951
I have a Map<String, Integer> otherMap
which maps properties of strings to some associated integer values.
Now I would like a TreeMap<String, String>
that orders the keys according to the associated integers in otherMap
.
How should I tackle this problem, and what's important to keep in mind?
(This is a follow-up on this question.)
Upvotes: 1
Views: 344
Reputation: 420951
When writing a comparator it's important to ensure that the results are consistent (i.e. are the same over time) and that it implements a total order.
When using the comparator in a TreeMap
it is also required that it is consistent with equals, which means that c.compare(e1, e2)
return 0
if and only if e1.equals(e2)
.
With this in mind, a correct comparator could be implemented as follows:
class MyComparator implements Comparator<String> {
Map<String, Integer> otherMap;
public MyComparator(Map<String, Integer> otherMap) {
this.otherMap = otherMap;
}
@Override
public int compare(String o1, String o2) {
int primary = otherMap.get(o1).compareTo(otherMap.get(o2));
if (primary != 0)
return primary;
// Fall back on comparing the string keys to ensure consistent results
return o1.compareTo(o2);
}
}
(It should be noted that it is also important that otherMap
never changes after it is passed to MyComparator
.)
In Java 8, the idiomatic solution would look like
Comparator.comparing(k -> otherMap.get(k))
.thenComparing(k -> k);
Upvotes: 2