当前位置: 首页 > 知识库问答 >
问题:

java 异常:比较方法违反了其通用约定

戚澄邈
2023-03-14

我已经检查了以前关于这个话题的帖子-这个和这个。尽管如此,我还是想不出在我下面给出的代码中违反合同的情况是如何发生的。

public class ScoreComparator 
implements Comparator<Map.Entry<?, Double>> {

public int compare(Map.Entry<?, Double> o1, 
        Map.Entry<?, Double> o2) {
    return o1.getValue().compareTo(o2.getValue());
}   
}

我使用它的方式如下:

List<Entry<String, Double>> entryList = 
        new ArrayList<Entry<String, Double>>(
                iterTypeScoreMap.get(keyToSort).entrySet());
Collections.sort(entryList, new ScoreComparator());

iterTypeScoreMap声明如下

ConcurrentHashMap<String, Map<String, Double>> iterTypeScoreMap;

映射(iterTypeScoreMap)在排序过程中可能会改变,这就是为什么我复制了一份列表,然后对它调用sort。

既然我使用的是Double的内置compareTo方法,那么这不应该考虑合同吗?另一件让调试变得困难的事情是,这种异常并不总是发生;仅在某些跑步过程中发生。这里可能有什么bug?

先谢谢你。

共有2个答案

佟颖逸
2023-03-14

我认为问题是a.compareTo(b)==0应该暗示a.equals(b)

但是,如果您的键不同但值相同,则两者将具有 a.compareTo(b)==0,但 a.equals(b) 将为

白泽语
2023-03-14

发生的情况是,由于条目值(分数)同时更改,您的排序顺序在排序操作期间发生了变化。

当条目本身被同时修改时,复制地图的entrySet()没有帮助。您必须深度复制集合,换句话说,也复制所有Entry对象,以防止错误。目前,您正在排序的列表引用了与原始地图相同的Entry对象。

 类似资料:
  • 我看到了很多关于这个问题的问题,并试图解决这个问题,但经过一个小时的谷歌搜索和大量的尝试&错误,我仍然无法修复它。我希望你们中的一些人抓住了这个问题。 知道吗?

  • 可能的重复: 为什么我的比较方法会抛出异常 — 比较方法违反了其一般合同! 我有这个代码: 有时它会引发以下异常: 为什么? 1) 我该如何避免呢?2) 我怎么能抓住这个例外? 提前谢谢。

  • 我有一个自己的,相对复杂的字符串比较器和一个庞大的字符串列表(~100个字符串,已经尝试减少,但问题不可重现),其中对它们进行排序会产生上述错误尝试使用Java 7排序。我想,规则 可能会被侵犯。找出违反合同的样品的最好方法是什么?

  • 我想通过dateLastContact比较两个“收件人”,如果相同,就通过地址进行比较。这是我的代码: 而且我总是有这个错误: 我尝试了很多方法,但是现在,我不知道该怎么办。你能帮我吗? 收件人类别:

  • 我发现了许多与此标题相关的重复问题,但没有一个与我的问题有关,因为我的问题无法通过崩溃追踪。我不断收到有关此标题的许多不同的崩溃。 检查此示例(仅在android 4上发生): 我通过研究发现,这种情况发生在比较/排序时,而忽略了某个条件。同时,在我的代码中,我没有使用文档/示例中提到的比较或排序方法。 非常感谢任何建议。

  • 问题内容: 我有以下代码: 每次我运行此代码时,都会出现此错误: 我使用OpenJDK7u3,当对象相等时返回0。有人可以向我解释这个错误吗? 问题答案: 如果您有任何NaN值,则可能会遇到这种情况: 例如: 所有 这些打印。因此,您可能会遇到以下两种情况:两个非NaN值都被认为与NaN“相等”,但是一个大于另一个。基本上,您应该弄清楚如何处理NaN值。当然,还要检查这确实是问题所在……您是否真的