为了账号安全,请及时绑定邮箱和手机立即绑定

Java错误:比较方法违反了它的一般契约

Java错误:比较方法违反了它的一般契约

海绵宝宝撒 2019-06-26 13:54:15
Java错误:比较方法违反了它的一般契约我看到了很多关于这方面的问题,并试图解决这个问题,但经过一个小时的谷歌和大量的尝试和错误,我仍然无法解决它。我希望你们中的一些人能理解这个问题。我得到的是:java.lang.IllegalArgumentException: Comparison method violates its general contract!     at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835)     at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453)     at java.util.ComparableTimSort.mergeForceCollapse(ComparableTimSort.java:392)     at java.util.ComparableTimSort.sort(ComparableTimSort.java:191)     at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)     at java.util.Arrays.sort(Arrays.java:472)     at java.util.Collections.sort(Collections.java:155)     ...这是我的比较器:@Overridepublic int compareTo(Object o) {     if(this == o){         return 0;     }     CollectionItem item = (CollectionItem) o;     Card card1 = CardCache.getInstance().getCard(cardId);     Card card2 = CardCache.getInstance().getCard(item.getCardId());     if (card1.getSet() < card2.getSet()) {         return -1;     } else {         if (card1.getSet() == card2.getSet()) {             if (card1.getRarity() < card2.getRarity()) {                 return 1;             } else {                 if (card1.getId() == card2.getId()) {                     if (cardType > item.getCardType()) {                         return 1;                     } else {                         if (cardType == item.getCardType()) {                             return 0;                         }                         return -1;                     }                 }                 return -1;             }         }         return 1;     }}知道吗?
查看完整描述

3 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

异常消息实际上非常具有描述性。它提到的合同是传递性*如果A > BB > C那么对于任何ABCA > C..我用纸和铅笔检查了它,您的代码似乎没有几个漏洞:

if (card1.getRarity() < card2.getRarity()) {
  return 1;

你不回来-1如果card1.getRarity() > card2.getRarity().


if (card1.getId() == card2.getId()) {
  //...}return -1;

你回来了-1如果ID不相等。你应该回来-11取决于哪个身份更大。


看看这个。除了可读性更强之外,我认为它实际上应该有效:

if (card1.getSet() > card2.getSet()) {
    return 1;}if (card1.getSet() < card2.getSet()) {
    return -1;};if (card1.getRarity() < card2.getRarity()) {
    return 1;}if (card1.getRarity() > card2.getRarity()) {
    return -1;}if (card1.getId() > card2.getId()) {
    return 1;}if (card1.getId() < card2.getId()) {
    return -1;}return cardType - item.getCardType();  //watch out for overflow!


查看完整回答
反对 回复 2019-06-26
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

它还与JDK的版本有关。如果它在JDK 6中做得很好,那么它可能会出现您所描述的JDK 7中的问题,因为JDK 7中的实现方法已经改变了。

看看这个:

描述:使用的排序算法java.util.Arrays.sort和(间接)java.util.Collections.sort已经被取代了。新的排序实现可能引发IllegalArgumentException如果它检测到Comparable违反Comparable合同。以前的实现忽略了这种情况。如果需要前面的行为,则可以使用新的系统属性,java.util.Arrays.useLegacyMergeSort,以恢复以前的合并行为。

我不知道确切原因。但是,如果在使用排序之前添加代码。会没事的。

System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");


查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 685 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信