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

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

知道吗?


海绵宝宝撒
浏览 686回答 3
3回答

慕尼黑的夜晚无繁华

异常消息实际上非常具有描述性。它提到的合同是传递性*如果A > B和B > C那么对于任何A,&nbsp;B和C:&nbsp;A > C..我用纸和铅笔检查了它,您的代码似乎没有几个漏洞:if&nbsp;(card1.getRarity()&nbsp;<&nbsp;card2.getRarity())&nbsp;{ &nbsp;&nbsp;return&nbsp;1;你不回来-1如果card1.getRarity() > card2.getRarity().if&nbsp;(card1.getId()&nbsp;==&nbsp;card2.getId())&nbsp;{ &nbsp;&nbsp;//...}return&nbsp;-1;你回来了-1如果ID不相等。你应该回来-1或1取决于哪个身份更大。看看这个。除了可读性更强之外,我认为它实际上应该有效:if&nbsp;(card1.getSet()&nbsp;>&nbsp;card2.getSet())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;}if&nbsp;(card1.getSet()&nbsp;<&nbsp;card2.getSet())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;};if&nbsp;(card1.getRarity()&nbsp;<&nbsp;card2.getRarity())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;}if&nbsp;(card1.getRarity()&nbsp;>&nbsp;card2.getRarity())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;}if&nbsp;(card1.getId()&nbsp;>&nbsp;card2.getId())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;}if&nbsp;(card1.getId()&nbsp;<&nbsp;card2.getId())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;-1;}return&nbsp;cardType&nbsp;-&nbsp;item.getCardType();&nbsp;&nbsp;//watch&nbsp;out&nbsp;for&nbsp;overflow!

神不在的星期二

它还与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",&nbsp;"true");
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java