相关疑难解决方法(0)

Android - 比较方法违反了其总合同

我已经看到了有关此异常的其他问题,但我的比较方法非常简单,我无法弄清楚它有什么问题,我无法使用我拥有的任何Android设备重现它.

我从我的Android应用程序的一些用户那里得到了这个例外,其中大多数似乎是在GS3或GS4这样的新设备上,我猜测它运行Java 7变种的合并排序.

这是我的比较方法:

            Collections.sort(collectionOfThings, new Comparator<Thing>()
            {
                public int compare(Thing lhs, Thing rhs) 
                {
                    //getDist() returns a Double with a capital D...perhaps that has something to do with it?
                    if(lhs.getDist() < rhs.getDist())
                    {
                        return -1;
                    }
                    if(lhs.getDist() == rhs.getDist())
                    {
                        return 0;
                    }

                    return 1;
                };
            });
Run Code Online (Sandbox Code Playgroud)

这是例外:

Caused by: java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.TimSort.mergeLo(TimSort.java:743)
    at java.util.TimSort.mergeAt(TimSort.java:479)
    at java.util.TimSort.mergeCollapse(TimSort.java:404)
    at java.util.TimSort.sort(TimSort.java:210)
    at java.util.TimSort.sort(TimSort.java:169)
    at java.util.Arrays.sort(Arrays.java:2038)
    at java.util.Collections.sort(Collections.java:1891)
Run Code Online (Sandbox Code Playgroud)

似乎仅限于Android 4.0+.任何帮助是极大的赞赏.

java collections mergesort android

3
推荐指数
1
解决办法
5215
查看次数

ArrayList.sort()中的IllegalArgumentException - 方法

我有以下异常,我不太清楚为什么:

java.lang.IllegalArgumentException:比较方法违反了它的一般合同!

在java.util.TimSort.mergeLo(TimSort.java:777)java.util.TimSort.mergeAt(TimSort.java:514)java.util.TimSort.mergeCollapse(TimSort.java:441)java.util. TimSort.sort(TimSort.java:245)java.util.Arrays.sort(Arrays.java:1512)at java.util.ArrayList.sort(ArrayList.java:1454)

我编写了以下JUnit测试来验证行为:

@Test
public void testComparator() {
    List<Boolean> item = new ArrayList<>();

    item.add(true);
    for (int i = 0; i < 1000000; i++) {
        item.add(false);
    }

    while(true) {
        System.out.println("Sorting");
        Collections.shuffle(item);

        item.sort((lineItem1, lineItem2) -> {
            if (lineItem1 && lineItem2) {
                return 0;
            } else if (!lineItem1) {
                return 1; 
            } else if (!lineItem2 ) {
                return -1;
            } 

            return 0;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我交换返回1并返回-1,它会突然无效.但为什么?这应该只改变排序顺序而不是破坏整个比较器.

我错过了什么?

java comparator java-8

3
推荐指数
1
解决办法
380
查看次数

Java Collections排序:比较方法违反了其一般合同

我知道它已经被问到并且已经回答了数百万次,但我仍然无法弄清楚为什么我在排序期间收到违规行为.这是我的代码:

Collections.sort(sorted, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject m1, MyObject m2) {
        // Actual energy comparison :-
        // THE higher the energy, the earlier in the list
        float delta = m1.getTotalEnergy() - m2.getTotalEnergy();

        if (delta > 0) {
            return 1;
        } else if (delta < 0) {
            return -1;
        } else {
            return 0;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

我收到这个错误

java.lang.IllegalArgumentException: Comparison method violates its general contract!  
        at java.util.TimSort.mergeHi(TimSort.java:895)  
        at java.util.TimSort.mergeAt(TimSort.java:512)  
        at java.util.TimSort.mergeForceCollapse(TimSort.java:453)  
        at java.util.TimSort.sort(TimSort.java:250)  
        at java.util.Arrays.sort(Arrays.java:1512)  
        at java.util.ArrayList.sort(ArrayList.java:1454)  
        at java.util.Collections.sort(Collections.java:175) …
Run Code Online (Sandbox Code Playgroud)

java sorting collections comparison

2
推荐指数
1
解决办法
1万
查看次数

"比较方法违反了其总合同!" - 查找小样本数据集

可能重复:
"比较方法违反了其总合同!"

我有一个更大的部分排序数据样本(> 700项)我想用Java 7排序并得到以下异常:

java.lang.IllegalArgumentException: Comparison method violates its general contract!
    at java.util.TimSort.mergeLo(TimSort.java:747)
    at java.util.TimSort.mergeAt(TimSort.java:483)
    at java.util.TimSort.mergeCollapse(TimSort.java:410)
    at java.util.TimSort.sort(TimSort.java:214)
    at java.util.TimSort.sort(TimSort.java:173)
    at java.util.Arrays.sort(Arrays.java:659)
    at java.util.Collections.sort(Collections.java:217)
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试降低数据集的大小,以便找到更简单的原因.我写了一个小应用程序,它从较大的集合中挑选一个随机子集来重现异常.

private static final int SUBSET_SIZE = 32;

public void testSorting() {
    ...
    final Random random = new Random();
    for (int i = 10000000; i-- > 0; ) {
        testFew(strings, random);
    }
}

private void testFew(List<String> strings, Random random) {
    final List<String> list = new ArrayList<String>();
    int index = 0;
    for (int i = …
Run Code Online (Sandbox Code Playgroud)

java sorting

1
推荐指数
2
解决办法
2509
查看次数

无法比较用户定义的对象进行排序(Java 8)

我有以下课程 -

public class Pair
{
    public double value;
    int id;

    Pair(){
        value=0;
        id=0;
    }
    Pair(double value, int id){
        this.value=value;
        this.id=id;
    }
}
Run Code Online (Sandbox Code Playgroud)

PairComparator类用于实现Comparator类

public class PairComparator implements Comparator<Pair>{
    @Override
    public int compare(Pair p1, Pair p2){
        return (int)(p2.value-p1.value);
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试按如下方式对Pair集合进行排序 -

List<Pair> list= new ArrayList<Pair>();
list.add(new Pair(5.2, 4));
list.add(new Pair(3.4, 5));
list.add(new Pair(10.3, 3));

Collections.sort(list, new PairComparator());
Run Code Online (Sandbox Code Playgroud)

但是我得到了以下错误 -

`线程中的异常"main"java.lang.IllegalArgumentException:比较方法违反了它的一般合同!

Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:895)
at java.util.TimSort.mergeAt(TimSort.java:512)
at java.util.TimSort.mergeCollapse(TimSort.java:435)
at java.util.TimSort.sort(TimSort.java:241) …
Run Code Online (Sandbox Code Playgroud)

java sorting collections

1
推荐指数
1
解决办法
481
查看次数

为什么compareTo()方法会在排序时导致合同违规?

我有一个文件名列表,并希望按以下顺序进行比较:

  • 所有以".rar"结尾的名字都应该出现带有".r01",".r02"的文件之前,......
  • 所有以".par2"结尾的名称都应该出现带有任何其他后缀的文件之后

所以我在compareTo我的一个Java类中使用以下方法:

public class DownloadFile implements Comparable<DownloadFile>
{
    // custom code ...

    @Override
    public int compareTo(DownloadFile other)
    {
        if(other == null)
            throw new NullPointerException("Object other must not be null");

        // special cases -- .rar vs .par2 etc.
        String thisStr = filename.toLowerCase();
        String oStr = other.getFilename().toLowerCase();
        if(thisStr.endsWith(".rar") && oStr.matches(".*\\.r[0-9]{2,}$"))
            return -1;
        if(thisStr.matches(".*\\.r[0-9]{2,}$") && oStr.endsWith(".rar"))
            return 1;
        if(!thisStr.endsWith(".par2") && oStr.endsWith(".par2"))
            return -1;
        if(thisStr.endsWith(".par2") && !oStr.endsWith(".par2"))
            return 1;

        // normal comparison based …
Run Code Online (Sandbox Code Playgroud)

java

1
推荐指数
1
解决办法
135
查看次数

为什么Comparator <Integer []>抛出异常?

我有一个例外

java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:868)
at java.util.TimSort.mergeAt(TimSort.java:485)
at java.util.TimSort.mergeCollapse(TimSort.java:408)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at Main.main(Main.java:64)
Run Code Online (Sandbox Code Playgroud)

使用此代码时:

Arrays.sort(arr, new Comparator<Integer[]>(){  //arr is 2D array
        public int compare(Integer[] o1, Integer[] o2){
            return o1[2]==o2[2]?0:o1[2]>o2[2]?1:-1;
        }
    });
Run Code Online (Sandbox Code Playgroud)

我认为这与不满足比较的传递性有关,但当我做了一点这样的改变时:

Arrays.sort(arr, new Comparator<Integer[]>(){  //arr is 2D array
        public int compare(Integer[] o1, Integer[] o2){
            return o1[2].compareTo(o2[2]); // here is the change
        }
    });
Run Code Online (Sandbox Code Playgroud)

不再生成异常.我无法理解这个问题的解释,因为我确信除了compareTo()方法之外,还可以使用关系运算符(>,<,=)来比较Integer实例

Integer x = 1;
Integer y = 2;
System.out.println(x<y);
Run Code Online (Sandbox Code Playgroud)

按预期打印true

任何机构都可以澄清吗?

java comparator

0
推荐指数
1
解决办法
187
查看次数

当我尝试订购联系人时,比较方法违反了其一般合同

我想比较我的联系人以获得字母顺序,但我有这个错误:

 java.lang.IllegalArgumentException: Comparison method violates its general contract!
Run Code Online (Sandbox Code Playgroud)

当我打电话时发生这种情况

Collections.sort(aVoid, new CustomComparator());
Run Code Online (Sandbox Code Playgroud)

这是我的CustomComparator:

public class CustomComparator implements Comparator<ContactItems> {
        @Override
        public int compare(ContactItems o1, ContactItems o2) {
            if (o1.getName() == null || o2.getName() == null)
                return 0;
            else
                return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的aVoid数组是@onPostExecute(List<ContactItems> aVoid)类的方法的结果AsyncTaskGetContacts extends AsyncTask<Void, Void, List<ContactItems>>

java android

-1
推荐指数
1
解决办法
37
查看次数

Java 比较问题 - 比较方法违反了其一般契约

我正在尝试对一些数字进行排序。我收到“java.lang.IllegalArgumentException:比较方法违反了其一般契约!” 当我执行以下代码时出现异常。

import org.apache.commons.lang3.StringUtils;

public class ComparatorTest {

    public static void main(String[] args) {
        List<String> ll = List.of("1.A", "1.A.1", "10.A", "10.A.1", "10.A.2", "10.A.3", "12.A", "12.A.1", "12.A.2",
                "12.A.4", "12.A.6", "1A.2", "2.A.1", "2.A.1.b", "2.A.1.b.1", "2.A.1.b.2", "2.A.1.b.3", "20.A.1",
                "20.A.1.a", "20.A.1.b", "20.A.1.b.1", "20.A.1.b.2", "3.A.1", "3.A.1.a", "3.A.1.a.1", "3.A.1.a.2",
                "3.A.1.a.3", "3.A.1.a.4", "3.A.1.b", "3.A.10", "6.A.1", "9.A.1");
        
        ArrayList<String> l2 = new ArrayList<>(ll);
        Collections.sort(l2, (obj1, obj2) -> {
            try {
                String[] prodClass1 = obj1.split("\\.");
                String[] prodClass2 = obj2.split("\\.");
                for (int i = 0; (i < prodClass1.length) && (i < …
Run Code Online (Sandbox Code Playgroud)

java sorting comparator java-8

-1
推荐指数
1
解决办法
106
查看次数

"比较方法违反了其总合同!"

我搜索了一些同样的问题,我知道原因.但是只发生一次坠机,所以我来这里问你可能会导致什么样的事故.

    Collections.sort(downloadTasks, new Comparator<DownloadTask>() {
        @Override
        public int compare(DownloadTask lhs, DownloadTask rhs) {
            if (lhs == null || rhs == null) return 0;
            return (int) (lhs.mTaskInfo.time - rhs.mTaskInfo.time);
        }
    });
Run Code Online (Sandbox Code Playgroud)

错误是:

java.lang.IllegalArgumentException:比较方法违反了它的一般合同!在java.util.TimSort.mergeHi(TimSort.java:864)java.util.TimSort.mergeAt(TimSort.java:481)java.util.TimSort.mergeCollapse(TimSort.java:406)java.util. TimSort.sort(TimSort.java:210)java.util.TimSort.sort(TimSort.java:169)java.util.Arrays.sort(Arrays.java:2010)at java.util.Collections.sort(Collections)的.java:1883)

如您所见,我通过其time成员比较两个对象.该timelong类型.

我认为崩溃可能来自:

  • 是否将long转换为int会导致崩溃?
  • if(lhs == null || rhs == null)返回0; 但理论上lhs和rhs都不为空.

编辑

如果lhs并且rhs可以为null,我该怎么办?

编辑Android版

在Android中,Long.compare()需要API 19.您可以在API 19下执行此操作:

public static int compare(long lhs, long rhs) {
    return lhs < rhs ? -1 : (lhs == …
Run Code Online (Sandbox Code Playgroud)

java

-2
推荐指数
1
解决办法
1125
查看次数

Java 8比较方法违反了比较器中的一般合同问题

虽然我使用下面的比较器来对我正在获得的对象进行排序比较方法违反了比较器中的一般合同问题.

final Set<Span> set = new TreeSet<Span>(new Comparator<Span>() {

        public int compare(final Span firstSpan, final Span secSpan) {
            BigInteger s1X0 = firstSpan.getCoordinates().getX0();
            BigInteger s1X1 = firstSpan.getCoordinates().getX1();
            BigInteger s2X0 = secSpan.getCoordinates().getX0();
            BigInteger s2X1 = secSpan.getCoordinates().getX1();

            BigInteger s1Y0 = firstSpan.getCoordinates().getY0();
            final BigInteger s2Y0 = secSpan.getCoordinates().getY0();

            if(s1X0.intValue() == s2X0.intValue() && s1X1.intValue() == s2X1.intValue() && s1Y0.intValue() == s2Y0.intValue()){
                return 0;
            }
            if ((s1Y0.intValue() - s2Y0.intValue() <= 5) && (s1Y0.intValue() - s2Y0.intValue() >= -5)) {
                return (s1X0.intValue()>s2X0.intValue()) ? 1 : -1;
            } else {
                if …
Run Code Online (Sandbox Code Playgroud)

java sorting comparator java-8

-4
推荐指数
1
解决办法
953
查看次数

标签 统计

java ×11

sorting ×5

comparator ×4

collections ×3

java-8 ×3

android ×2

comparison ×1

mergesort ×1