Sto riscontrando questo problema da tempo, ho cercato molte domande StackOverflow ma non ho potuto risolvere il mio problema.Perché il mio confronto mostra a volte IllegalArgumentException?
Ho anche chiesto una domanda simile prima e ci hanno dato il suggerimento di utilizzare,
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
Essa non ha risolto il mio problema. Non ho mai ottenuto questa eccezione su nessuno dei miei dispositivi di prova, ma alcuni dei miei utenti lo hanno segnalato regolarmente. Sono davvero all'oscuro di come risolverlo.
L'eccezione
questa è l'eccezione che sto ottenendo,
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:2023)
at java.util.Collections.sort(Collections.java:1883)
o, talvolta, questo,
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:864)
at java.util.TimSort.mergeAt(TimSort.java:481)
at java.util.TimSort.mergeCollapse(TimSort.java:406)
at java.util.TimSort.sort(TimSort.java:210)
at java.util.TimSort.sort(TimSort.java:169)
at java.util.Arrays.sort(Arrays.java:2010)
at java.util.Collections.sort(Collections.java:1883)
quello che ho fatto
enum FileItemComparator implements Comparator<FileItem> {
//Using ENUM
NAME_SORT {
public int compare(FileItem o1, FileItem o2) {
int result = 0;
if (o1 != null && o2 != null) {
String n1 = o1.getFileName();
String n2 = o2.getFileName();
if (n1 != null && n2 != null)
result = n1.compareTo(n2);
}
return result;
}
},
DATE_SORT {
public int compare(FileItem o1, FileItem o2) {
int result = 0;
if (o1 != null && o2 != null) {
String d1 = o1.getFileDate();
String d2 = o2.getFileDate();
if (d1 != null && d2 != null) {
Long l1 = Long.valueOf(d1);
Long l2 = Long.valueOf(d2);
if (l1 != null && l2 != null) {
result = l1.compareTo(l2);
}
}
}
return result;
}
},
SIZE_SORT {
public int compare(FileItem o1, FileItem o2) {
int result = 0;
if (o1 != null && o2 != null) {
File f1 = o1.getItem();
File f2 = o2.getItem();
if (f1 != null && f2 != null) {
result = Long.valueOf(f1.length()).compareTo(Long.valueOf(f2.length()));
}
}
return result;
}
};
public static Comparator<FileItem> descending(final Comparator<FileItem> other) {
return new Comparator<FileItem>() {
public int compare(FileItem o1, FileItem o2) {
return -1 * other.compare(o1, o2);
}
};
}
public static Comparator<FileItem> getComparator(final FileItemComparator... multipleOptions) {
return new Comparator<FileItem>() {
public int compare(FileItem o1, FileItem o2) {
for (FileItemComparator option : multipleOptions) {
int result = option.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
};
}
}
Questo è come mi sto ordinamento,
Collections.sort(dirs, FileItemComparator.getComparator(FileItemComparator.NAME_SORT));
Il problema
Sono sicuro che c'è qualcosa di sbagliato nel metodo confrontare con dipendenze transitive. Ho provato molto e non riesco a risolverlo. In realtà, non ho mai avuto questo problema in nessuno dei miei dispositivi di test, ma i miei utenti lo segnalano costantemente.
Spero che qualcuno qui sia in grado di cogliere il problema e aiutarmi a risolverlo una volta per tutte.
Aggiornato Codice (Grazie a @Eran)
ho pensato che sarebbe stato meglio per aiutare gli altri, pubblicando il codice aggiornato completo. Aiuterà molte persone che affrontano lo stesso problema.
enum FileItemComparator implements Comparator<FileItem> {
//Using ENUM
NAME_SORT {
public int compare(FileItem o1, FileItem o2) {
if (o1 == null) {
if (o2 == null) {
return 0;
} else {
return 1; // this will put null in the end
}
} else if (o2 == null) {
return -1;
}
String n1 = o1.getFileName();
String n2 = o2.getFileName();
if (n1 == null) {
if (n2 == null) {
return 0;
} else {
return 1; // this will put null names after non null names
}
} else if (n2 == null) {
return -1;
}
return n1.compareTo(n2);
}
},
DATE_SORT {
public int compare(FileItem o1, FileItem o2) {
if (o1 == null) {
if (o2 == null) {
return 0;
} else {
return 1; // this will put null in the end
}
} else if (o2 == null) {
return -1;
}
String d1 = o1.getFileDate();
String d2 = o2.getFileDate();
if (d1 == null) {
if (d2 == null) {
return 0;
} else {
return 1; // this will put null names after non null names
}
} else if (d2 == null) {
return -1;
}
Long l1 = Long.valueOf(d1);
Long l2 = Long.valueOf(d2);
if (l1 == null) {
if (l2 == null) {
return 0;
} else {
return 1; // this will put null names after non null names
}
} else if (l2 == null) {
return -1;
}
return l1.compareTo(l2);
}
},
SIZE_SORT {
public int compare(FileItem o1, FileItem o2) {
if (o1 == null) {
if (o2 == null) {
return 0;
} else {
return 1; // this will put null in the end
}
} else if (o2 == null) {
return -1;
}
File f1 = o1.getItem();
File f2 = o2.getItem();
if (f1 == null) {
if (f2 == null) {
return 0;
} else {
return 1; // this will put null in the end
}
} else if (f2 == null) {
return -1;
}
Long l1 = Long.valueOf(f1.length());
Long l2 = Long.valueOf(f2.length());
if (l1 == null) {
if (l2 == null) {
return 0;
} else {
return 1; // this will put null names after non null names
}
} else if (l2 == null) {
return -1;
}
return l1.compareTo(l2);
}
};
public static Comparator<FileItem> descending(final Comparator<FileItem> other) {
return new Comparator<FileItem>() {
public int compare(FileItem o1, FileItem o2) {
return -1 * other.compare(o1, o2);
}
};
}
public static Comparator<FileItem> getComparator(final FileItemComparator... multipleOptions) {
return new Comparator<FileItem>() {
public int compare(FileItem o1, FileItem o2) {
for (FileItemComparator option : multipleOptions) {
int result = option.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
};
}
}
Potrebbe essere correlato con uno degli argomenti "nullo" e non l'altro, tuttavia restituire "0"? – Mena
@Mena Sì, questo è possibile. Buona scoperta Potete per favore aiutarmi con un codice funzionante? –
sembra [Eran] (http://stackoverflow.com/users/1221571/eran) ha appena fatto :) – Mena