我已经看到了有关此异常的其他问题,但我的比较方法非常简单,我无法弄清楚它有什么问题,我无法使用我拥有的任何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.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,它会突然无效.但为什么?这应该只改变排序顺序而不是破坏整个比较器.
我错过了什么?
我知道它已经被问到并且已经回答了数百万次,但我仍然无法弄清楚为什么我在排序期间收到违规行为.这是我的代码:
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) 可能重复:
"比较方法违反了其总合同!"
我有一个更大的部分排序数据样本(> 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) 我有以下课程 -
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) 我有一个文件名列表,并希望按以下顺序进行比较:
所以我在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.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.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.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) 我搜索了一些同样的问题,我知道原因.但是只发生一次坠机,所以我来这里问你可能会导致什么样的事故.
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
成员比较两个对象.该time
是long
类型.
我认为崩溃可能来自:
如果lhs
并且rhs
可以为null,我该怎么办?
在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) 虽然我使用下面的比较器来对我正在获得的对象进行排序比较方法违反了比较器中的一般合同问题.
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 ×11
sorting ×5
comparator ×4
collections ×3
java-8 ×3
android ×2
comparison ×1
mergesort ×1