How to create a TreeMap with a comparator based on “external” values

最后都变了- 提交于 2019-12-11 13:38:58

问题


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.)


回答1:


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);


来源:https://stackoverflow.com/questions/29005998/how-to-create-a-treemap-with-a-comparator-based-on-external-values

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!