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

错误:比较法违反了其一般约定

徐俊楚
2023-03-14

我知道有很多问题与这个主题有关,但我不能完全理解是什么导致了这个错误

 Collections.sort(noteList,new Comparator<ClassNote>(){
        @Override
        public int compare(ClassNote b, ClassNote a) {
           DateFormat formatter = new SimpleDateFormat("MMMM dd HH:mm", Locale.US);
           try {
               Date date2 = formatter.parse(b.getCallDate());
               Date date1 = formatter.parse(a.getCallDate());
               if ( date1 == null ) {
                   if ( date2 == null) {
                       return 0;
                   }
                   return 1;
               }
               if ( date2 == null ) {
                   return -1;
               }
               return date2.compareTo(date1);
           } catch (ParseException e) {
               e.printStackTrace();
               return 1;
           }
        }
    });

有人知道为什么它不起作用以及如何修复它吗?

共有2个答案

娄建义
2023-03-14

如果比较 ClassNote 的两个实例 ab,并且解析其中一个实例将引发异常:

< code>compare(a,b)将返回< code>a较大。

比较(b, a)将返回b较大。

比较返回值不一致。

司徒博容
2023-03-14

我认为在这种情况下,最好的方案是,不要关注“我如何使比较函数一致”,而是问“我希望排序数组看起来像什么”?当你处理特殊情况时,这一点尤其重要。一旦你找到了正确的顺序,就写一个比较函数来给出这个顺序。

在这里,您正在处理三类ClassNote

    < li> ClassNote具有有效日期的对象 < li> ClassNote对象,其中解析日期返回< code>null < li> ClassNote对象,其中解析日期会引发异常

第一类很简单:您希望对象按日期排序。(您还必须弄清楚当两个< code>ClassNote具有相同的日期时会发生什么,但是在这种情况下,您可能不关心顺序,这很好。在某些情况下,您可能希望日期相同的项目按其他字段排序。)

对于#2和#3,您希望它们在结果中的哪个位置?到目前为止,看起来您首先需要<code>null</code>,但您还没有处理解析异常。我可以看到两种简单的方法:

    < li >将< code>null视为异常。那么所有的空值和异常情况将会以某种顺序出现,并且会混合在一起,但是这可能没问题。 < li >将它们分组,使#2项目先出现,然后是#3项目,然后是具有有效日期的项目。或者反过来:#3,然后#2,然后是有效日期。

任何一种方法都可以,但你必须对你想要什么做出决定。

假设你采用方法#1。现在你必须安排事情,这样当你比较#2项和#3项时,结果是0;当你将#2或#3项目与#1项目进行比较时,#2或#1项目总是更少。您可以修改现有代码

 Date date2 = formatter.parse(b.getCallDate());
 Date date1 = formatter.parse(a.getCallDate());

对此:

 Date date2 = parseOrReturnNull(b.getCallDate());
 Date date1 = parseOrReturnNull(a.getCallDate());

其中 parseOrReturnNull 是一个帮助程序方法,它使用 formatter.parse(),捕获 ParseException,如果有异常则返回 null。现在,逻辑的其余部分将确保出于排序目的以相同的方式处理 null 和解析异常。

如果要将 null 和异常分别分组,一种解决方案是添加一个应用于每个 ClassNote 的“类别”变量。该类别将按正确的顺序指示 ClassNote 所在的类别:因此,如果您首先想要空值,然后是异常,然后是有效日期,则可以将类别 0 设置为,1 表示异常,2 表示有效日期。(更好的是,使用枚举)。然后,对于每个日期,您将同时计算类别和日期。事实上,最好声明一个新类:

class ComparisonDate {
    int category;  // or enum
    Date date;     // meaningful only if the date is valid
}

使用一个helper方法,该方法接受ClassNote并返回ComparisonDate。然后,您可以使用如下代码比较两个ComparisonDate

if (cd1.category != cd2.category) {
    return Integer.compare(cd1.category, cd2.category);
} else if (cd1.category == 2) {    // 2 means they have valid dates
    return cd1.date.compareTo(cd2.date);
} else {        // ComparisonDates are in same category and dates aren't
                // meaningful
    return 0;   // so treat them as equal
}

我可能切换了 cd1cd2,但你可以解决这个问题。

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

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

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

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

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

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