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

IllegalArgument异常:比较方法违反一般合同

陈君之
2023-03-14

对不起,又是一个问题,但我根本不明白这里发生了什么,或者我哪里出错了。

概述:我有一个ArrayList包含多个电影-对象。它们有一个date和一个staringTime。我想按以下条件对它们进行排序,优先级如下所列:

  • 日期
  • 开始时间

但是当这样做时,我得到以下错误:

java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.TimSort.mergeHi(TimSort.java:864)
    at java.util.TimSort.mergeAt(TimSort.java:481)
    at java.util.TimSort.mergeForceCollapse(TimSort.java:422)
    at java.util.TimSort.sort(TimSort.java:219)
    at java.util.TimSort.sort(TimSort.java:169)
    at java.util.Arrays.sort(Arrays.java:2010)
    at java.util.Collections.sort(Collections.java:1883)
    at org.pbdevelopement.cineapp.MainActivity.sortByStartingTime(MainActivity.java:208)

我得到的:我在JavaFX项目中也有同样的事情发生,但是在那里我使用ArrayList.sort()而不是Collections.sort()。我需要转换为Collections.sort(),因为显然Android还不支持ArrayList.sort()方法。

这是启动排序和定义< code>Comperator的方法:

private ArrayList<Movie> sortByStartingTime(ArrayList<Movie> list) {
    Collections.sort(list, new Comparator<Movie>() { //This line is MainActivity.java: 208  ;)
        @Override
        public int compare(Movie o1, Movie o2) {
            int comparison = o1.getDate().compareTo(o2.getDate());
            if (comparison == 0) {
                return o1.getStartingTime().compareTo(o2.getStartingTime());
            }
            return comparison;
        }
    });
    return list;
}

如您所见,我比较了电影中的两个date,如果它们相等,我将继续比较开始时间。以下是我的DateKeeperTimeKeeper类中的两个比较()方法(我可能应该承认它们是自己编写的):

public int compareTo(DateKeeper toCompare) {
    Calendar startDate = getAsCalendar();
    Calendar endDate = toCompare.getAsCalendar();
    long diff = endDate.getTimeInMillis() - startDate.getTimeInMillis();//in Milli seconds
    return (int) (diff / (1000 * 60 * 60 * 24));
}

我不返回 -1,01,因为我也想使用此方法来计算两个日期之间的差异。我已经阅读了比较方法,发现这应该不是问题。

public int compareTo(TimeKeeper toCompare) {
    int toReturn = Integer.compare(this.getValue(), toCompare.getValue());
    return toReturn;
}

getValue()只返回所谓的MINUTES_OF_DAY

我不明白这是如何违反方法契约的。据我所知,Comperator是可传递的(或者不是?)自反的和对称的。那么为什么我会收到这个错误消息呢?

共有1个答案

长孙绍辉
2023-03-14

你的问题是,你减去后一天的毫秒数。这可能导致两个节目

public int compareTo(DateKeeper toCompare) {
    Calendar startDate = getAsCalendar();
    Calendar endDate = toCompare.getAsCalendar();
    long diff = (endDate.getTimeInMillis()/ (1000 * 60 * 60 * 24)) - (startDate.getTimeInMillis()/ (1000 * 60 * 60 * 24));//in Milli seconds
    return (int) diff;
}

或者将两个日历对象上的时间都设置为午夜

 类似资料:
  • 下面的代码在Java 6上运行时抛出“Java比较方法违反了它的通用契约”。但是,在Java 7上,它不会抛出同样的异常。有什么问题?。如何修改这段代码以在Java 7上抛出异常?。

  • 我有一个类字段,和。我需要使用对它们进行排序,但我得到了一个异常: java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 我的< code>compareTo方法: 请帮我找出compareTo方法中的错误。谢了。

  • 我在尝试对节点的数组列表进行排序时遇到了这个错误。我尝试了大多数解决方案,但没有一个在我的案例中有效。 此代码为 它适用于小输入,但是当输入数量很大时,它会给出这个错误。我也读过比较方法中的传递性规则,但我不知道它是如何在这种情况下应用的。 先谢谢你。

  • 我目前正在Java中对集合进行排序。我收到了错误消息“比较方法违反了它的一般契约”。我也理解这个错误消息,但我(主要)使用Long类型的构建比较方法。所以我不知道,在这种情况下,排序方法仍然违反了契约。这是我的代码: 这里是错误:

  • 下面的代码是Dave Koelle的AlphanumComparator的编辑版本。编辑包含将空字符串排序到列表末尾或 底部的代码。问题是 为了解决我的问题,我调查了它并找到了诸如比较器没有 等原因; 在正确的位置。我还在Java错误数据库中发现了一条评论,上面写着 java.util.Arrays.sort和java.util.Collections.sort(间接地)使用的排序算法被替换了,新

  • 我看到我的应用程序在一些中国 Android 手机上发生了很多崩溃,并出现错误:比较方法违反了其总合同! 我读过这与Collections.sort有关。 我不太确定的是,这是否是因为我的自定义比较器。 以下是错误发生的地方: 比较器是这样的: 所以我不太确定比较器是否搞砸了什么,或者我是否需要以不同的方式进行collections.sort调用 感谢任何帮助