2

我正在尝试根据我拥有的唯一(非工作)答案来回答我自己的老问题。

这个想法是为了简化按值排序的映射的创建:

public class SortedByValueMap<K, V extends Comparable<V>> implements Comparator<K> {

    private final Map<K, V> map = new TreeMap<K, V>(this);

    @Override
    public int compare(K o1, K o2) {
        return map.get(o1).compareTo(map.get(o2)); // <-- line #19
    }

    public Map<K, V> getMap() {
        return map;
    }

}

然后,在实例化它时:

Map<String, Integer> map = new SortedByValueMap<String, Integer>().getMap();
map.put("a", 9); // works great
map.put("z", 0); // throws a StackOverflowException

这是堆栈跟踪:

Exception in thread "main" java.lang.StackOverflowError
    at java.util.TreeMap.get(TreeMap.java:255)
    at main.Main$SortedByValueMap.compare(Main.java:19)
    at java.util.TreeMap.getEntryUsingComparator(TreeMap.java:351)
    at java.util.TreeMap.getEntry(TreeMap.java:322)
    at java.util.TreeMap.get(TreeMap.java:255)

知道为什么它会循环以及如何解决它吗?

4

1 回答 1

2

问题是该get()方法调用了compare()提供的比较器的方法——你的类——和你的compare()方法调用get(),所以我们最终会绕圈子跑

at java.util.TreeMap.get(TreeMap.java:255) <--
at main.Main$SortedByValueMap.compare(Main.java:19)
at java.util.TreeMap.getEntryUsingComparator(TreeMap.java:351)
at java.util.TreeMap.getEntry(TreeMap.java:322)
at java.util.TreeMap.get(TreeMap.java:255) <--

进入此循环是因为在您将元素放入非空地图时TreeMap使用提供的Comparatorput

于 2013-06-20T13:12:14.757 回答