我知道这个问题的答案已经提供了很多变种,但我找不到我的具体查询。
我希望有一个按值排序的地图,我需要在将数据输入之前创建它。我想出了下面的代码来创建它
private Map<String, Integer> mapUserScore = new ConcurrentSkipListMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int i1=mapUserScore.get(o2);
int i2=mapUserScore.get(o1);
if(mapUserScore.get(o2)!=null && mapUserScore.get(o1)!=null){
int compare = mapUserScore.get(o2)-(mapUserScore.get(o1));
if(compare==0)compare=-1;
return compare;
}else
return 0;
}
});
所以基本上我希望地图中的条目按整数值降序排序,以便最高得分者位于顶部。 但是,在插入第一个键值对时执行此操作,程序将退出以下异常
Exception in thread "Thread-0" java.lang.StackOverflowError
at java.util.concurrent.ConcurrentSkipListMap.comparable(ConcurrentSkipListMap.java:658)
at java.util.concurrent.ConcurrentSkipListMap.doGet(ConcurrentSkipListMap.java:821)
at java.util.concurrent.ConcurrentSkipListMap.get(ConcurrentSkipListMap.java:1626)
在跟踪时,我发现行 int i1 = mapUserScore.get(o2)会导致此异常。 任何人都可以帮助我了解stackoverflow的原因是什么? 我在想,因为在任何项目存储在地图之前,代码试图通过使用get()方法对其进行排序来获取它,因此它会进入一些递归调用并导致异常。
答案 0 :(得分:1)
如果我理解正确,您希望能够快速获得与名称相关联的分数(因此需要地图),并且您希望能够以最高的顺序遍历tyhe名称 - 分数对先得分。
我只想使用HashMap<String, NameScore>
(其中键是名称,值是名称 - 得分对)。这将为您提供O(1)查找。当您需要按分数排序的名称 - 分数对时,从地图的ArrayList<NameScore>
创建一个新的values()
,对其进行排序,然后将其返回。
答案 1 :(得分:0)
get()方法使用比较器来查找值。您不能在比较器中使用get,否则您将获得堆栈溢出。
一个简单的解决方法是将分数包含在密钥中并对其进行排序。
class NameScore implement Comparable<NameScore> {
String name;
int score;
}
BTW:当比较器返回0时,这表示它是重复的,被丢弃。除非您每个分数只需要一个名称,否则您需要比较分数和名称。