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

获取错误:比较方法违反其一般约定

路思源
2023-03-14

我已经尝试了许多可能的解决方案,在网上给出的像设置系统属性和转换在双,但仍然得到相同的错误:

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)

以下是我的代码:

        System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
        Collections.sort(docs, new Comparator<FeedDocument>() {
            public int compare(FeedDocument o1, FeedDocument o2) {

                int year1 = 0;
                int year2 = 0;
                int returnResult = 0;
                if (o1.containsKey(FeedConstants.PUBLICATION_YEAR)
                        && o2.containsKey(FeedConstants.PUBLICATION_YEAR)
                        && o1.get(FeedConstants.PUBLICATION_YEAR) != null
                        && (o1.get(FeedConstants.PUBLICATION_YEAR) instanceof String)
                        && o2.get(FeedConstants.PUBLICATION_YEAR) != null
                        && (o2.get(FeedConstants.PUBLICATION_YEAR) instanceof String)) {

                    String firstyear = (String) o1.get((FeedConstants.PUBLICATION_YEAR));
                    String secondyear = (String) o2.get((FeedConstants.PUBLICATION_YEAR));

                    if (firstyear.equals(secondyear)) {
                        return 0;
                    } else if (firstyear != null && !firstyear.isEmpty() && secondyear != null
                            && !secondyear.isEmpty()) {

                        year1 = Integer.parseInt(firstyear.trim());

                        year2 = Integer.parseInt(secondyear.trim());

                        // int result = year2 - year1;
                        // if (result > 0) {
                        // returnResult = 1;
                        // } else if (result < 0) {
                        // returnResult = -1;
                        // }
                        return Double.compare(year2, year1);
                    }

                } else {
                    returnResult = 0;
                }
                return returnResult;
            }
        });

共有2个答案

充浩波
2023-03-14

爱德华·彼得斯的答案在诊断您的问题时是正确的,因为您的比较方法不会产生一致的(传递的)结果。

解决此问题的最佳方法是在compare方法中使用以下方法:

if (o1.get(FeedConstants.PUBLICATION_YEAR) instanceof String) {
    if (o2.get(FeedConstants.PUBLICATION_YEAR) instanceof String) {
        // Perform the comparison here like you are
    } else {
        /*
         * This could also be 1, the key is to have it consistent
         * so the final sorted list clearly separates the FeedDocuments
         * with a String PUBLICATION_YEAR and those without one.
         */
        return -1;
    }
} else if (o2.get(FeedConstants.PUBLICATION_YEAR) instanceof String) {
    /*
     * In this case, o1 doesn't have a String PUBLICATION_YEAR and o2
     * does, so this needs to be the opposite of the return value
     * 6 lines up to be consistent.
     */
     return 1;
} else {
     /*
      * Consider all FeedDocuments without a String PUBLICATION_YEAR
      * to be equivalent, otherwise you could do some other comparison
      * on them here if you wanted.
      */
     return 0;
}

关键是,如果您只关心被排序的列表的子集(带有< code>String出版年份的< code>FeedDocument,那么您需要首先将它们与您不关心被排序的列表的其余部分分开(当一个< code>FeedDocument有< code>String出版年份而另一个没有时,通过返回1或-1)。然后,您可以自由地对所需的子集进行排序,而不会产生不一致的结果。

司信厚
2023-03-14

我很确定我知道这里发生了什么。。。

假设:

o1.get(FeedConstants.PUBLICATION_YEAR) != null
o2.get(FeedConstants.PUBLICATION_YEAR) == null
o3.get(FeedConstants.PUBLICATION_YEAR) != null

然后:

compare (o1, o2); //returns 0
compare (o2, o3); //returns 0
compare (o1, o3); //returns not 0

所以你声称o1==o2==o3o1!=o3

 类似资料:
  • 问题内容: 我看到了很多与此有关的问题,并试图解决该问题,但是经过一个小时的搜索和大量的试验和错误后,我仍然无法修复它。我希望你们中的一些人能抓住问题。 这是我得到的: 这是我的比较器: 任何想法? 问题答案: 异常消息实际上是描述性的。这里所指的合同是传递:如果和那么对于任意的。我用纸和铅笔检查了一下,你的代码似乎有几个孔: 如果你不返回。 如果id不相等,则返回。你应该返回-1或1根据哪个ID

  • 我知道有很多问题与这个主题有关,但我不能完全理解是什么导致了这个错误 有人知道为什么它不起作用以及如何修复它吗?

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

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

  • 我所拥有的 我有此代码,用于根据名称,日期或大小对文件进行排序。 但我得到了这个错误, 我的一些用户得到了这个错误,我在崩溃报告中看到了它。但我自己无法以任何方式重现这个错误。 任何人都可以帮助我找到问题。我似乎真的花了很多时间,但找不到任何东西。请帮我吗? 提前谢谢。

  • 我收到以下错误: 比较方法违反了其总合同! 这是我的比较法 我想比较项目的分数。但是当分数相同时,我想按名称对它们进行排序。 我需要更改什么,为什么会出现这个错误? 编辑: 分数是一个,itemname一个。 这是 ComparableItem 类: 这是MenuList项目类: