简体   繁体   English

如何使用基于“外部”值的比较器创建TreeMap

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM