[英]How to create a TreeMap with a comparator based on “external” values
I have a Map<String, Integer> otherMap
which maps properties of strings to some associated integer values. 我有一个Map<String, Integer> otherMap
,它将字符串的属性映射到一些关联的整数值。
Now I would like a TreeMap<String, String>
that orders the keys according to the associated integers in otherMap
. 现在,我想要一个TreeMap<String, String>
,它根据otherMap
关联的整数对键进行otherMap
。
How should I tackle this problem, and what's important to keep in mind? 我应该如何解决这个问题,并且要牢记什么是重要的?
(This is a follow-up on this question .) (这是此问题的后续内容。)
When writing a comparator it's important to ensure that the results are consistent (ie 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)
. 在TreeMap
使用比较器时,还要求它与equals保持一致 ,这意味着c.compare(e1, e2)
当且仅当e1.equals(e2)
返回0
。
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
.) (应注意,将otherMap
传递给MyComparator
后再也不要更改也很重要。)
In Java 8, the idiomatic solution would look like 在Java 8中,惯用的解决方案看起来像
Comparator.comparing(k -> otherMap.get(k))
.thenComparing(k -> k);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.