Il seguente programma genera la seguente eccezione:Perché questo programma utilizza Collections.sort non riesce solo per gli elenchi di dimensioni 32 o superiori?
java.lang.IllegalArgumentException: Comparison method violates its general contract!
Capisco il problema con il Comparator
. Vedi Unable to replicate : "Comparison method violates its general contract!"
Non capisco perché fallisce solo per List
s di dimensione 32 o superiore. Qualcuno può spiegare?
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;
}
}
}
}
}
possano riprodursi. Sembra sempre fallire a lungo 32. Probabilmente alcuni dettagli di implementazione oscuri dell'algoritmo di ordinamento ... O forse a partire dalla lunghezza 32 viene usato un algoritmo diverso? –
@tobias_k Sono solo curioso di sapere quali sono i dettagli di implementazione. Ovviamente i 3 downvoters non lo sono! –