Je sais que cela pose un problème depuis un certain temps et j’ai vérifié toutes les réponses que je pouvais obtenir précédemment, mais celle-ci ne fonctionne toujours pas.
L'objet 'équipage' représente les membres d'équipage avec des grades et d'autres objets. La comparaison doit être faite en comparant "assign_rank", une valeur int, et si cette valeur est égale dans les deux cas, alors "is_trainer", un booléen, fera la différence.
Cette méthode fonctionnait très bien tant qu'elle fonctionnait avec Java <7. Mais depuis Java 7, je continue à avoir celle-ci:
Java.lang.IllegalArgumentException: Comparison method violates its general contract!
at Java.util.ComparableTimSort.mergeLo(ComparableTimSort.Java:714)
at Java.util.ComparableTimSort.mergeAt(ComparableTimSort.Java:451)
at Java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.Java:376)
at Java.util.ComparableTimSort.sort(ComparableTimSort.Java:182)
at Java.util.ComparableTimSort.sort(ComparableTimSort.Java:146)
at Java.util.Arrays.sort(Arrays.Java:472)
at Java.util.Collections.sort(Collections.Java:155)
at dormas_flightlog.Query.getCrew(Query.Java:714)
Voici la source, où certaines parties potentiellement dangereuses ont déjà été commentées, mais cela ne fonctionne toujours pas:
public class crew implements Serializable, Comparable<crew> {
private static final long serialVersionUID = 36L;
private int flightID = 0;
private int assigned_rank = 25;
private boolean is_trainer = false;
...
@Override
public int compareTo(crew him) {
int myRank = this.getAssigned_rank();
int hisRank = him.assigned_rank;
if (this == him) {
return 0;
}
if (myRank > hisRank) {
return 1;
}
if (myRank < hisRank) {
return -1;
}
if (myRank == hisRank) {
// if (is_trainer && !o.is_trainer) {
// i = 1;
// }
// if (!is_trainer && o.is_trainer) {
// i = -1;
// }
// if (is_trainer && o.is_trainer) {
// i = 0;
// }
// if (!is_trainer && !o.is_trainer) {
// i = 0;
// }
return 0;
}
return 0;
}
@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + this.assigned_rank;
hash = 31 * hash + (this.is_trainer ? 1 : 0);
return hash;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
int myRank = this.getAssigned_rank();
int hisRank = 0;
if (o instanceof crew) {
crew him = (crew) o;
hisRank = him.assigned_rank;
} else {
return false;
}
if (myRank > hisRank) {
return false;
}
if (myRank < hisRank) {
return false;
}
if (myRank == hisRank) {
// if (is_trainer && !o.is_trainer) {
// i = 1;
// }
// if (!is_trainer && o.is_trainer) {
// i = -1;
// }
// if (is_trainer && o.is_trainer) {
// i = 0;
// }
// if (!is_trainer && !o.is_trainer) {
// i = 0;
// }
return true;
}
return false;
}
}
Implémenter equals () était juste un essai pour résoudre ce problème. L'exception donnée est avec ou sans égal (). Je ne vois pas en quoi la méthode compareTo viole son contrat. Toute aide est grandement appréciée .... un jour, ce code doit fonctionner avec Java 7 et je ne sais pas comment ... Merci
regarde ça:
De http://www.Oracle.com/technetwork/Java/javase/compatibility-417013.html#source
Domaine: API: Utilitaires Synopsis: Comportement de tri mis à jour pour les tableaux et Les collections peuvent générer une exception IllegalArgumentException
Description: l’algorithme de tri utilisé par Java.util.Arrays.sort et (indirectement) par Java.util.Collections.sort a été remplacé. Le nouveau L'implémentation de sort peut générer une exception IllegalArgumentException si elle détecte un comparable qui viole le contrat comparable. La précédente la mise en œuvre ignorait silencieusement une telle situation Si le précédent le comportement est souhaité, vous pouvez utiliser le nouveau système propriété Java.util.Arrays.useLegacyMergeSort, pour restaurer la version précédente comportement mergesort.
Nature de l'incompatibilité: comportementale
RFE: 6804124
Pour des informations plus détaillées, voir la base de données de bogues référence ici .
vous avez peut-être juste des valeurs NaN
que vous comparez via Collections.sort(...)
, cela me pose un problème et cette exception a même eu la bonne implémentation de la méthode compare(obj1, obj2)
! Regarde ça!
J'ai pu résoudre cette erreur car il s'agissait d'un bogue dans jdk7.
ici j'ai trouvé la solution:
"La méthode de comparaison viole son contrat général!" - TimSort et GridLayout
Fondamentalement, je devais simplement ajouter le
Java_OPTS="$Java_OPTS -Djava.util.Arrays.useLegacyMergeSort=true"
à mon jboss
Malheureusement, aucune des solutions ne fonctionne pour Android. TimSort est utilisé profondément dans le ViewGroup d'Android relatif à addChildrenForAccessibility qui apparaît sous Java 7 & 8. Aucun code d'utilisateur n'est impliqué dans une comparaison.
D'après d'autres rapports, il est lié au fait que RelativeLayout comporte des éléments qui se chevauchent, comme cela se fait couramment. Par exemple, un TextView qui apparaît sur une image, ou deux éléments au même endroit, où vous n'en définissez qu'un seul visible à la fois . https://code.google.com/p/Android/issues/ detail? id = 55933
Je n'ai trouvé aucun moyen de contourner le bogue. Vous ne pouvez pas définir une option -Djava dans Android Studio ou Eclipse (du moins, que j'ai pu trouver). Forcer l'utilisation de Java 1.6 devrait fonctionner, mais ne fonctionne pas. On dirait que les tablettes et téléphones Fire plus récents d'Amazon sont beaucoup plus sensibles à ce bogue que les autres appareils.
Il y a des rumeurs selon lesquelles Java 9 aurait une solution, telle qu'une option d'exécution qui fonctionnerait, mais avec un bogue existant depuis des années, je doute qu'elle soit corrigée, en particulier compte tenu de l'animosité entre Oracle et Google. Dans l’affirmative, le bogue est peut-être profondément ancré dans le code Android et devrait y être corrigé. Avec plus d'un milliard d'appareils sur le marché, ce n'est pas une solution viable pour tous les appareils existants.