简体   繁体   English

Java 错误:java.lang.IllegalArgumentException:比较方法违反其一般约定

[英]Java Error: java.lang.IllegalArgumentException: Comparison method violates its general contract

I am working on a old application which was originally written in Java 6 and which was upgraded to Java 7 a couple of years ago.我正在开发一个旧应用程序,它最初是用 Java 6 编写的,几年前升级到 Java 7。

In this application i am using a Collection.Sort to sort a list with a custom compare method by implementing Comparator interface.在这个应用程序中,我使用 Collection.Sort 通过实现Comparator接口使用自定义compare方法对列表进行排序。 Type of objects in the list are CompanySchedule which have 3 properties companyName , Schedule and expirationdate .列表中的对象类型是CompanySchedule ,它具有 3 个属性companyNameScheduleexpirationdate

List can contain multiple objects with same companyName but with unique expiration date.列表可以包含多个具有相同companyName但具有唯一到期日期的对象。 Below compare function sorts the list in ascending order of companyName and with in the same companyName list descending order of expiration date.下面的比较函数按 companyName 的升序对列表进行排序,并在同一个 companyName 列表中按到期日期的降序排列。 Below is the method implementation.下面是方法的实现。

    public int compare(CompanySchedule c1, CompanySchedule c2) {
        int returnVal = 0;
        int value = c1.getCompany().getName().compareTo(c2.getCompany().getName());
        if (value == 0){
            if (c1.getUseExpirationDate() == null || c2.getUseExpirationDate() == null){
                returnVal = -1;
            }
            else{
                int chkdate = c1.getUseExpirationDate().compareTo(c2.getUseExpirationDate());
                if (chkdate == 0){
                    returnVal = 0;
                }
                else if (chkdate > 0){
                    returnVal = -1;
                }
                else if (chkdate < 0){
                    returnVal = 1;
                }
            }
        }
        else if (value < 0){
            returnVal = -1;
        }
        else if (value > 0){
            returnVal = 1;
        }


        return returnVal;
    }

I know that when the transitive property is not met in the compare method implementation above error java.lang.IllegalArgumentException: Comparison method violates its general contract will be thrown.我知道当上面的compare方法实现中没有满足传递属性时,会抛出错误java.lang.IllegalArgumentException: Comparison method violates its general contract

can some one help in identifying the where this method will violates the transitive property.有人可以帮助确定此方法将在哪里违反传递属性。 Thanks for the Help.谢谢您的帮助。

I think that one problem is here:我认为一个问题就在这里:

if (c1.getUseExpirationDate() == null || c2.getUseExpirationDate() == null){
                returnVal = -1;
}

If a.getUseExpirationDate() == null and also b.getUseExpirationDate() == null, you will get that a < b and b < a which means a < a.如果 a.getUseExpirationDate() == null 并且 b.getUseExpirationDate() == null,您将得到 a < b 和 b < a,这意味着 a < a。

This breaks consistency.这打破了一致性。 There might be more problems in this method but I have not checked it all.这种方法可能有更多问题,但我还没有全部检查过。

Good luck.祝你好运。

EDIT编辑

How about this code?这段代码怎么样?

public int compare(CompanySchedule c1, CompanySchedule c2) {
        int returnVal = 0;
        int value = c1.getCompany().getName().compareTo(c2.getCompany().getName());
        if (value == 0) {
            if (c1.getUseExpirationDate() == null && c2.getUseExpirationDate() != null) {
                returnVal = -1;
            } else if (c1.getUseExpirationDate() != null && c2.getUseExpirationDate() == null) {
                returnVal = 1;
            } else if (c1.getUseExpirationDate() == null && c2.getUseExpirationDate() == null) {
                returnVal = 0;
            } else {
                int chkdate = c1.getUseExpirationDate().compareTo(c2.getUseExpirationDate());
                if (chkdate == 0) {
                    returnVal = 0;
                } else if (chkdate > 0) {
                    returnVal = -1;
                } else if (chkdate < 0) {
                    returnVal = 1;
                }
            }
        } else if (value < 0) {
            returnVal = -1;
        } else if (value > 0) {
            returnVal = 1;
        }


        return returnVal;
    }

I have tried not to change it too much, for comparability, but it should be refactored.为了可比性,我尽量不对其进行太多更改,但应该对其进行重构。 Basically it determines that nulls are smaller than other values.基本上它确定空值小于其他值。

I know I am late to this, once I found the solution I had basically forgotten I had asked this question.我知道我迟到了,一旦我找到了解决方案,我基本上忘记了我问过这个问题。 so as I mentioned the application was written in Java 6 and then was upgraded to Java 7, as per my understanding the internal implementation of Collections.所以正如我所提到的,根据我对 Collections 内部实现的理解,该应用程序是用 Java 6 编写的,然后升级到 Java 7。 Sort method changes the algorithm used from Merge sort to Tim Sort, Merge Sort ignore the Transitivity property of the compare method implementation, however Tim sort required the the compare method implementation to be transitive else the above exception would be thrown, since we had an legacy app we did not want to change anything from the code so we used jvm argument java.util.Arrays.useLegacyMergeSort=true Merge Sort internally in the sort implementation Sort 方法将使用的算法从 Merge sort 更改为 Tim Sort,Merge Sort 忽略了 compare 方法实现的 Transitivity 属性,但是 Tim sort 要求 compare 方法实现是可传递的,否则会抛出上述异常,因为我们有遗留应用程序我们不想更改代码中的任何内容,因此我们在排序实现中使用了 jvm 参数 java.util.Arrays.useLegacyMergeSort=true Merge Sort

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.IllegalArgumentException:比较方法违反了它的一般约定,在 java7 中给出了错误 - java.lang.IllegalArgumentException: Comparison method violates its general contract giving Error in java7 错误:java.lang.IllegalArgumentException:即使使用替代方法,比较方法也违反了其常规协定 - Error: java.lang.IllegalArgumentException: Comparison method violates its general contract even using workaround 随机错误-java.lang.IllegalArgumentException:比较方法违反了其一般约定 - Random error - java.lang.IllegalArgumentException: Comparison method violates its general contract Java 7:java.lang.IllegalArgumentException:比较方法违反了其一般合同 - Java 7 : java.lang.IllegalArgumentException: Comparison method violates its general contract Java sort抛出java.lang.IllegalArgumentException:比较方法违反了其一般合同 - Java sort throws java.lang.IllegalArgumentException: Comparison method violates its general contract Java Rest Template throws java.lang.IllegalArgumentException: Comparison method violates its general contract - Java Rest Template throws java.lang.IllegalArgumentException: Comparison method violates its general contract java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 日期 - java.lang.IllegalArgumentException: Comparison method violates its general contract! java.util.Date 为什么我得到这个异常 java.lang.IllegalArgumentException:比较方法违反了它的一般契约 - Why did I get this exception java.lang.IllegalArgumentException: Comparison method violates its general contract 获取java.lang.IllegalArgumentException:比较方法违反了其一般约定! 排序算法应该是100%稳定的 - Getting java.lang.IllegalArgumentException: Comparison method violates its general contract! with a sort algo that should be 100% stable 线程“AWT-EventQueue-0”中的异常java.lang.IllegalArgumentException:比较方法违反了其总契约 - Exception in thread “AWT-EventQueue-0” java.lang.IllegalArgumentException: Comparison method violates its general contract
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM