Java错误:比较方法违反其一般合同 [英] Java error: Comparison method violates its general contract

查看:834
本文介绍了Java错误:比较方法违反其一般合同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到很多问题,并试图解决这个问题,但经过一小时的谷歌搜索和大量的试验,错误,我仍然无法解决它。

 prettyprint-override>  java.lang.IllegalArgumentException:比较方法违反了它的一般合同! 
at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835)
在java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453)
在java.util.ComparableTimSort.mergeForceCollapse (ComparableTimSort.java:392)
在java.util.ComparableTimSort.sort(ComparableTimSort.java:191)
在java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
在java.util.Collections.sort(Collections.java:155)
在magiccollector.gui.Main $ 1.actionPerformed(Main.java :85)
at org.pushingpixels.flamingo.api.common.AbstractCommandButton.fireActionPerformed(AbstractCommandButton.java:616)
at org.pushingpixels.flamingo.api.common.AbstractCommandButton $ ActionHandler.actionPerformed(AbstractCommandButton .java:568)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at org.pushingpixels.flamingo.api.common.model.ActionRepeatableButtonModel.setPressed(ActionRepeatableButtonModel.java:123 )
at org.pushingpixels.flamingo.internal.ui.common.BasicCommandButtonListener.mouseReleased(BasicCommandButtonListener.java:147)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289)
在java.awt.Component.processMouseEvent(Component.java:6504)

在javax.swing.JComponent.processMouseEvent(JComponent。 java:3321)
在java.awt.Component.processEvent(Component.java:6269)
在java.awt.Container.processEvent(Container.java:2229)
在java.awt .Component.dispatchEventImpl(Component.java:4860)
在java.awt.Container.dispatchEventImpl(Container.java:2287)
在java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
在java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
在java.awt.LightweightDispatcher.dispatchEvent( Container.java:4422)
在java.awt.Container.dispatchEventImpl(Container.java:2273)
在java.awt.Window.dispatchEventImpl(Window.java:2713)
在java .awt.Component.dispatchEvent(Component.java:4686)
在java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
在java.awt.EventQueue.access $ 000(EventQueue.java: 101)
at java.awt.EventQueue $ 3.run(EventQueue.java:666)
at java.awt.EventQueue $ 3.run(EventQueue.java:664)
at java.security .AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue $ 4.run(EventQueue.java:680)
at java.awt.EventQueue $ 4.run(EventQueue.java:678)
at java.security.AccessController.doPrivileged (Native Method)
at java.security.ProtectionDomain $ 1.doIntersectionPrivilege(ProtectionDomain.java:76)
在java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
在java。 (EventDispatchThread.java:127)
在java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
在java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
在$ java.awt.EventDispatchThread.pumpEventsForHierarchy
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
在java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
在java.awt.EventDispatchThread.run (EventDispatchThread.java:90)

这是我的比较器:

  @Override 
public 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;
}
}

有什么想法吗?

解决方案

异常消息实际上是很描述性的。它提到的合同是

转移:if A> B B> C A> C 。我用纸和铅笔检查,你的代码似乎有几个洞:

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

您不会返回 -1 if card1.getRarity()> card2.getRarity()






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

您返回 -1 t相等。您应该根据哪个ID较大,返回 -1 1






看看这个。除了更加可读,我认为它应该工作:

  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(); //注意溢出!


I saw many questions about this, and tried to solve the problem, but after one hour of googling and a lots of trial & error, I still can't fix it. I hope some of you catch the problem.

This is what I get:

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)
    at magiccollector.gui.Main$1.actionPerformed(Main.java:85)
    at org.pushingpixels.flamingo.api.common.AbstractCommandButton.fireActionPerformed(AbstractCommandButton.java:616)
    at org.pushingpixels.flamingo.api.common.AbstractCommandButton$ActionHandler.actionPerformed(AbstractCommandButton.java:568)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at org.pushingpixels.flamingo.api.common.model.ActionRepeatableButtonModel.setPressed(ActionRepeatableButtonModel.java:123)
    at org.pushingpixels.flamingo.internal.ui.common.BasicCommandButtonListener.mouseReleased(BasicCommandButtonListener.java:147)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289)
    at java.awt.Component.processMouseEvent(Component.java:6504)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6269)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4860)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2713)
    at java.awt.Component.dispatchEvent(Component.java:4686)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:680)
    at java.awt.EventQueue$4.run(EventQueue.java:678)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

And this is my comparator:

@Override
public 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;
    }
}

Any idea?

解决方案

The exception message is actually pretty descriptive. The contract it mentions is transitivity: if A > B and B > C then for any A, B and C: A > C. I checked it with paper and pencil and your code seems to have few holes:

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

you do not return -1 if card1.getRarity() > card2.getRarity().


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

You return -1 if ids aren't equal. You should return -1 or 1 depending on which id was bigger.


Take a look at this. Apart from being much more readable, I think it should actually work:

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!

这篇关于Java错误:比较方法违反其一般合同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆