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

Collections.sort方法

吕德业
2023-03-14

我有字符串的比较器,它被转换成日期。当我将这个比较器传递给集合时。sort()方法我得到了java。lang.IllegalArgumentException:比较法违反其总合同!。

我读过一些关于这个例外的文章,但我真的不明白为什么会出现这个例外。知道吗?

private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm");   

    Comparator<String> comparator = new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        if (o1 == null && o2 == null) {
                            return 0;
                        }
                        if (o1 == null) {
                            return 1;
                        }
                        if (o2 == null) {
                            return -1;
                        }
                        try {
                            Date first = sdf.parse(o1);
                            Date second = sdf.parse(o2);
                            return first.compareTo(second);
                        } catch (Exception ignored) {
                            return 0;
                        }
                    }
                };

共有3个答案

田俊爽
2023-03-14

不错。你的问题其实没那么难...想象你有三根弦...

Date 1=correct Date string for“今日”Date 2=correct Date string for“明日”Date 3=XYZ(一个不正确的日期字符串,在解析时会引发异常)

<代码>日期1

但现在的魔术/问题是:

Date 3==Date 1-由于您的异常处理

Date 3==Date 2-也正因为如此(对于这两个,您将返回0)

所以有一个日期对1和2都是相等的,但是1和2不相等。

问问自己,你会把日期3放在你的名单上的什么地方?它必须与日期1处于相同的“位置”(因为它与==0进行比较),与日期2处于相同的“位置”(同样,它与==0进行比较)。但日期1和日期2不在同一位置。这是不可能的,因此你得到的是“比较法违反了它的总合同!”例外

许兴文
2023-03-14

问题出在try catch块中。

即使其中1个日期是不可解析的,您也会返回0(这意味着对象是相等的)。

现在我们来看看这个条件。

str1 = "invalid";
str2 = "10/10/2015"; //Consider this to be valid format.
str3 = "12/10/2015";

现在,让我们回顾一下比较,

  1. 比较str1和str2:返回0(意思是相等)
  2. 比较str1和str3:返回0(表示相等)

这意味着,当您比较str2和str3时,那么应该是相等的。(A=BandA=C表示B=C)。

但是当它比较时,它返回一个负数。因此是例外。

唐修明
2023-03-14

如果引发异常,则返回0。这意味着当任何一个参数不能被解析时,它们都被认为是相等的。想想这个例子:

a = "01/01/2015"
b = "01/01/2016"
c = "xxx"

然后你就可以

comparator.compare(a,c) = 0
comparator.compare(b,c) = 0

但是

comparator.compare(a,b) != 0

解决方案:尝试分别解析每个字符串,在异常情况下使用null,如下所示:

私有SimpleDataFormat sdf=新SimpleDataFormat(“dd/MM/yyyy HH:MM”);

Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        Date first;
        try {
            first = sdf.parse(o1);
        } catch (Exception ignored) {
            first = null;
        }
        Date second;
        try {
            second = sdf.parse(o2);
        } catch (Exception ignored) {
            second = null;
        }

        if (first == second) {
            return 0;
        }
        if (first == null) {
            return 1;
        }
        if (second == null) {
            return -1;
        }
        return first.compareTo(second);
    }
};
 类似资料:
  • 我的目标是对名单上的人进行排序。我使用比较器接口的比较方法。 我已经创建了三个类。即 Person类是一个简单的类,包含两个字段(name、age),也包含getters。然后,在我的AgeComaparator类中,我实现了比较器接口,并将Person类作为类型参数传递。 ageComparator.java 排序Example.java 我将Eclipse IDE用于此应用程序,在

  • 问题内容: 我试图根据类A的int排序类B中名为BinOrder的类型A的列表。 但是我收到此错误行Collections.sort(BinOrder); A类: B级: 问题答案: 为了能够使用单参数版本上的,应该实现的接口:

  • 问题内容: 为了清楚起见,我试图找出Collections.sort(list,new MyComp())方法如何按顺序调用compare方法。 我有一个带有雇员及其个人号码(k)的LinkedList:这些号码是:{1,2,3,4,5,6} MyComparator中的compare(Object o1,Object o2)方法返回一些数字(即与该问题无关)。sort()如何比较方法?它使用参数

  • 我遇到了Java内置的collections.sort()方法的问题。我试图对一个名为TreeNode的自定义对象类型的ArrayList进行排序。我在过去成功地使用了这种方法,并希望外界看看我是否遗漏了任何明显的东西。 我希望通过一个整数字段对这些TreeNode对象进行排序,该字段都被称为myWeight。myWeight是特定字符在文本文件中出现的次数的整数表示。在我的项目中,我使用了一个名

  • 问题内容: 朋友,我是Java系列的新手。我想问一下方法是否仅用于/通过类型的集合。我无法对以下代码进行排序: 我知道这是用于独特的元素。但是有什么办法可以对这个集合进行排序吗? 问题答案: 该错误是因为Collections类仅支持列表。 要对您的收藏进行排序,您可以尝试执行以下操作: 希望这可以帮助。