以下程序引发以下异常:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
我了解的问题Comparator
。请参阅无法复制:“比较方法违反了它的一般约定!”
我不明白为什么它只会List
在大小为32或更大的情况下失败。谁能解释?
class Experiment {
private static final class MyInteger {
private final Integer num;
MyInteger(Integer num) {
this.num = num;
}
}
private static final Comparator<MyInteger> COMPARATOR = (r1, r2) -> {
if (r1.num == null || r2.num == null)
return 0;
return Integer.compare(r1.num, r2.num);
};
public static void main(String[] args) {
MyInteger[] array = {new MyInteger(0), new MyInteger(1), new MyInteger(null)};
Random random = new Random();
for (int length = 0;; length++) {
for (int attempt = 0; attempt < 100000; attempt++) {
List<MyInteger> list = new ArrayList<>();
int[] arr = new int[length];
for (int k = 0; k < length; k++) {
int rand = random.nextInt(3);
arr[k] = rand;
list.add(array[rand]);
}
try {
Collections.sort(list, COMPARATOR);
} catch (Exception e) {
System.out.println(arr.length + " " + Arrays.toString(arr));
return;
}
}
}
}
}
它取决于实现,但是在openjdk
8
中,将根据MIN_MERGE(等于32)检查数组的大小。这避免了对mergeLo
/
的调用,mergeHi
后者会引发异常。
从JDK / jdk / openjdk / 7u40-b43 8-b132 7-b147-8-b132 /
java.util.TimSort
:static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c, T[] work, int workBase, int workLen) { assert c != null && a != null && lo >= 0 && lo <= hi && hi <=
a.length;
int nRemaining = hi - lo; if (nRemaining < 2) return; // Arrays of size 0 and 1 are always sorted // If array is small, do a "mini-TimSort" with no merges if (nRemaining < MIN_MERGE) { int initRunLen = countRunAndMakeAscending(a, lo, hi, c); binarySort(a, lo, hi, lo + initRunLen, c); return; } /** * March over the array once, left to right, finding natural runs, * extending short natural runs to minRun elements, and merging runs * to maintain stack invariant. */ TimSort<T> ts = new TimSort<>(a, c, work, workBase, workLen); int minRun = minRunLength(nRemaining); do { // Identify next run int runLen = countRunAndMakeAscending(a, lo, hi, c); // If run is short, extend to min(minRun, nRemaining) if (runLen < minRun) { int force = nRemaining <= minRun ? nRemaining : minRun; binarySort(a, lo, lo + force, lo + runLen, c); runLen = force; } // Push run onto pending-run stack, and maybe merge ts.pushRun(lo, runLen); ts.mergeCollapse(); // Advance to find next run lo += runLen; nRemaining -= runLen; } while (nRemaining != 0); // Merge all remaining runs to complete sort assert lo == hi; ts.mergeForceCollapse(); assert ts.stackSize == 1; }
以下程序引发以下异常: 我理解的问题。请参阅无法复制:“比较方法违反了其总合同! 我不明白为什么它只对大小为32或更大的s失败。有人能解释吗?
问题内容: 在应使用相同的列表时,我看到一些不一致之处。(Python 2.7.5) 有人有一个简单的解释吗? 问题答案: 使用列表文字,VM会创建具有设置长度的列表。当将序列传递给构造函数时,元素将被一个接一个地添加(通过),因此在适当时调整了列表的大小。由于调整大小操作是为了分摊成本而进行的,因此最终列表通常会比源列表大。
问题内容: 我正在学习Java 8文档。我知道最大数组大小定义为均值2 ^ 31 – 8 = 2147483639 。然后,我集中讨论了为什么要减去8 或减去? 有些人根据文档给出了一些逻辑。因此,对于标题字,减去8。但是在这种情况下,如果标题字需要大于8,那么答案是什么? 请在此基础上澄清我。预先感谢您的合作。 问题答案: 阅读上述有关Java内存管理的文章,其中清楚指出 我认为这适用于Arra
问题内容: 限制Java JVM上Permgen空间大小的目的是什么?为什么不总是将其设置为等于最大堆大小?Java为什么默认为这么少的64MB?他们是否正在试图通过这种方式迫使人们注意代码中的Permgen问题? 如果我的应用使用85MB的permgen,那么将其设置为96MB可能是安全的,但是如果它只是主堆的一部分,为什么还要设置得如此之小呢?允许JVM使用堆允许的PermGen效率不高吗?
我在一个项目中使用Spring/JPA,我有一个实体在列表上有@onetomany注释,另一个实体有@manytoone注释。尽管当我通过父实体的id检索父实体时,返回的列表(子实体)的大小始终为0 测试的文本版本 此父实体 如有任何帮助,不胜感激,谢谢!
问题内容: 我了解,当您添加/删除组件时,需要然后单击。但是,我正在更改多边形的状态。最初显示图像,但是当我按左右键时,图像不会移动。如果我移动窗口,则gui将更新。为什么当我按下按键时它没有更新? 问题答案: 在听众之后打电话。 另外,我建议使用KeyBindings而不是