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

如何解析Java集合。sort()比较方法违反了它的一般约定异常

董康平
2023-03-14

我正在使用 Collections.sort 根据时间字段按升序对列表进行排序。下面是代码

private String getShipmentInpickingTime(List<Shipments> shipments) {
        logger.info("in getShipmentInpickingTime");
        DateFormat sdf = new SimpleDateFormat("hh:mm");

        Collections.sort(shipments, (o1, o2) -> {
            try {
                if ((!"null".equals(o1.getShipmentinpickingtime())
                        && !StringUtils.isEmpty(o1.getShipmentinpickingtime()))
                        && (!"null".equals(o2.getShipmentinpickingtime())
                                && !StringUtils.isEmpty(o2.getShipmentinpickingtime()))) {
                    return sdf.parse(o1.getShipmentinpickingtime()).compareTo(sdf.parse(o2.getShipmentinpickingtime()));
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
            int count1 = 0;
            return count1;
        });

此方法引发异常--

java.lang.IllegalArgumentException: Comparison method violates its general contract.

关于这个问题,我浏览了谷歌,上面说我在比较大对象和小对象。我试着颠倒物体的顺序,但没有成功。

共有2个答案

公孙胡媚
2023-03-14

您没有提到哪行代码会引发此错误。我不确定您在这里使用了哪些StringUtils,com.sun.deploy.util。StringUtils没有。isEmpty()方法。所以我重新实现了它。

以下是针对您的问题的工作代码:

public static void main(String[] args){
    getShipmentInpickingTime(new ArrayList<Shipments>(){{
        add(new Shipments("12:00"));
        add(new Shipments("12:03"));
        add(new Shipments("12:02"));
    }});
}

private static void getShipmentInpickingTime(List<Shipments> shipments) {
    DateFormat sdf = new SimpleDateFormat("hh:mm");

    System.out.println(shipments.toString());
    Collections.sort(shipments, (o1, o2) -> {
        try {
            if ((!"null".equals(o1.getShipmentPickingTime())
                    && !(o1.getShipmentPickingTime() == null || o1.getShipmentPickingTime().length() < 1))
                    && (!"null".equals(o2.getShipmentPickingTime())
                    && !(o2.getShipmentPickingTime() == null || o2.getShipmentPickingTime().length() < 1))) {
                return sdf.parse(o1.getShipmentPickingTime()).compareTo(sdf.parse(o2.getShipmentPickingTime()));
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    });

    System.out.println(shipments.toString());
}

货件类内容:

public class Shipments {

    private String shipmentPickingTime;

    public Shipments(String shipmentPickingTime) {
        this.shipmentPickingTime = shipmentPickingTime;
    }

    public String getShipmentPickingTime() {
        return shipmentPickingTime;
    }

    public void setShipmentPickingTime(String shipmentPickingTime) {
        this.shipmentPickingTime = shipmentPickingTime;
    }

    @Override
    public String toString() {
        return "Shipments{" +
                "shipmentPickingTime='" + shipmentPickingTime + '\'' +
                '}';
    }
}

输出:

[装运{装运拣件时间='12:00'}, 装运{装运拣件时间='12:03'}, 装运{装运拣货时间='12:02'}] [装运{装运拣件时间='12:00'}, 装运{装运拣件时间='12:02'}, 装运{装运拣件时间='12:03'}]

龙兴学
2023-03-14

如果任一元素解析失败,则仅捕获一次异常。

考虑三次装运,时间如下:< br> A - 12:34
B - 34:56
C -空< br >

使用您的比较器,比较(A, C)返回0,比较(B, C)将返回0,但比较(A, B)将返回非零结果,从而违反传递性的一般契约。

一种简单的方法是使用Comparator.comparing语法分别解析每个元素:

DateFormat sdf = new SimpleDateFormat("hh:mm");

shipments.sort(Comparator.comparing(
                   Shipments::getShipmentinpickingtime, 
                   Comparator.nullsLast(Comparator.comparing(time -> {
                       try {
                           if (!"null".equals(time) && !StringUtils.isEmpty(time)) {
                               return sdf.parse(time);
                           }
                       } catch (ParseException ignoe) {
                           // Not a valid time
                       }
                       return null;
                   })))
              );
 类似资料:
  • 使用自定义比较器执行< code > Collection.sort using >时,我得到一个< code > Java . lang . illegalargumentexception:Comparison方法违反了它的一般约定 我理解这是一个问题,因为该方法是不可传递的。在我的比较器中,调用了多个方法,我确定了违反此规则的代码段。然而,我无法修复它,也看不到它的问题。

  • 一切似乎都运行良好(几天),但我只遇到了一次问题,并且很难重现该问题。 “比较方法违反了其总合同!”被抛出,完全让我措手不及。我有以下几点: 我的染色体类别: 我有一个ArrayList,我使用了两个Collections。排序(MyList)和集合。排序(MyList,Collections.reverseOrder())。到目前为止,他们仍在正常工作。我在100次跑步中只遇到过一次错误。这个实

  • 问题内容: 您好,以下是我的比较器的比较方法。我不确定是什么问题。我在堆栈溢出时查找了其他类似标题的问题和答案,但不确定我的方法有什么问题,但我一直在获取java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 任何帮助将不胜感激 添加我得到的异常 问题答案: 您的方法 不是可 传递的 。如果和,则必须等于。 现在考虑这种情况: 对于,和,假设方法返回以下

  • 我们的一些用户在排序列表时遇到了这个异常。抛出它的代码是 而 getTime() 的类型为 “long”

  • 我知道有很多类似的问题,通过阅读这些问题的答案,我得到了很大的帮助,但是我无法看到我的客户如何面对这个问题。只有一个客户面临这个问题。 我有一个列表,我正在使用比较器界面对该列表进行排序。你们中有人看到以下代码有问题吗? 这就是我调用这个函数的方式 我知道这种情况下的主要问题是传递性。然而,我不知道是什么违反了这条规则。 这如何getSampleDateTime()返回日期Fri Apr 09 1

  • 嗨,下面是我的比较器的比较方法。我不知道哪里出了问题。我查了关于堆栈溢出的其他类似标题的问题和答案,但不确定我的方法有什么问题,但我不断得到java.lang.IllegalArgument异常:比较方法违反了它的一般合同! 任何帮助将不胜感激 添加我得到的异常