Maison Java javaDidacticiel Rapport de tri Java : la méthode de comparaison viole sa solution générale d'exception contractuelle

Rapport de tri Java : la méthode de comparaison viole sa solution générale d'exception contractuelle

Jun 30, 2017 am 10:35 AM
method

Cet article vous présente principalement la solution à l'exception du rapport de tri en Java : la méthode de comparaison viole son contrat général. L'introduction dans l'article est très détaillée et a une certaine valeur de référence et d'apprentissage pour tous les amis qui en ont besoin. venez nous rejoindre.

Préface

Un Comparison method violates its general contract est apparu dans un morceau de code Java de tri en ligne la semaine dernière, et je l'ai appris en résolvant ce problème. Certains les connaissances sont résumées et partagées ici.

Raison de l'exception

L'exception provoquée par ce tri apparaîtra dans les versions supérieures à java7, donc si votre JDK est de 6 Si vous passez à la version 7 ou 8, vous devez faire attention à cette exception.

Dans la liste de compatibilité de java7, il y a une description de l'incompatibilité de ce type :

Area: API: Utilities
Synopsis: Updated sort behavior for Arrays and Collections may throw an IllegalArgumentException
Description: The sorting algorithm used by java.util.Arrays.sort and (indirectly) by java.util.Collections.sort has been replaced. The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract. The previous implementation silently ignored such a situation.
If the previous behavior is desired, you can use the new system property, java.util.Arrays.useLegacyMergeSort, to restore previous mergesort behavior.
Nature of Incompatibility: behavioral
RFE: 6804124
Copier après la connexion

J'ai lu dans les informations que java7 a commencé à introduire l'algorithme de tri Timsort . J'ai toujours pensé que la plupart des algorithmes de tri intégrés à la bibliothèque standard étaient des tris rapides. Maintenant, j'ai appris que de nombreux multi-langues utilisent Timsort en interne. Ensuite, j'ai trouvé cette phrase sur Wikipédia :

t a été implémenté par Tim Peters en 2002 pour être utilisé dans le langage de programmation Python.

Ce classement est donc naturellement nommé d'après lui.

Ensuite, j'ai trouvé cette comparaison de tri d'images sur Internet :

On peut constater que Timsort est plus performant que QuickSort.

Ce blog ne discutera pas de l'implémentation de Timsort en détail (il semble que cet algorithme soit assez compliqué). Je pourrais écrire un autre blog pour discuter de Timsort séparément. En termes simples, Timsort combine le tri par fusion et le tri par insertion. Cet algorithme nécessite clairement une augmentation ou une diminution monotone stricte lors de la mise en œuvre pour garantir la stabilité de l'algorithme.

  • sgn(compare(x, y)) == -sgn(compare(y, x))

  • ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0

  • compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z

Cela ressemble beaucoup à la symétrie et aux relations transitives des ensembles apprises dans les cours de mathématiques discrètes.

La raison de l'exception est donc que l'algorithme de tri n'est pas assez rigoureux. En fait, le code commercial n'est souvent pas aussi rigoureux que la technologie pure. Par exemple, pour un algorithme comme celui-ci :

Sélectionner le prix le plus bas parmi les vols

Puis si deux prix bas égaux existent en même temps, selon la logique de trouver le prix le plus bas prix, s'il est écrit comme ceci :

if (thisPrice < lowPrice){
 lowPrice = thisPrice;
}
Copier après la connexion

Alors la position des prix bas est "premier arrivé, premier servi".

Mais si cela est réalisé :

if(thisPrice <= lowPrice){
 lowPrice = thisPrice;
}
Copier après la connexion

Alors les prix bas ultérieurs couvriront les précédents, et cela deviendra un « retardataire vient en premier ». La Programmation rencontre souvent les deux problèmes du premier arrivé, premier servi et du dernier arrivé, premier.

Donc pour celui ci-dessus, il est nécessaire de fournir un jugement rigoureux et une implémentation de la fonction de comparaison de taille. Donc si cela ressemble à ceci :

return x > y ? 1 : -1;
Copier après la connexion

alors cette condition n'est pas remplie.

Mais notre logique est plus compliquée que cela. Il s'agit en fait d'une telle condition de tri. Trier par :

  • prix Si les prix sont égaux, celui avec l'heure de départ la plus précoce sera classé en premier.

  • Si les horaires de départ sont également égaux, les règles seront les suivantes :

  • Non-partagé non-stop>non-stop> non partagé> Les attributs de l'arrêt sont sélectionnés selon la priorité Si ces attributs sont tous égaux, ils ne peuvent être considérés que comme égaux.

Le problème avec cette fonction de jugement est donc :

public compareFlightPrice(flightPrice o1, flightPrice o2){
 // 非经停非共享
 if (o1.getStopNumber() == 0 && !o1.isShare()) {
 return -1;
 } else if (o2.getStopNumber() == 0 && !o2.isShare()) {
 return 1;
 } else {
 if (o1.getStopNumber() == 0) {
  return -1;
 } else if (o2.getStopNumber() == 0) {
  return 1;
 } else {
  if (!o1.isShare()) {
  return -1;
  } else if (!o2.isShare()) {
  return 1;
  } else {
  if (o1.getStopNumber() > 0) {
   return -1;
  } else if (o2.getStopNumber() > 0) {
   return 1;
  } else {
   return 0;
  }
  }
 }
 }
}
Copier après la connexion

Cette fonction a un problème évident de premier arrivé, premier servi. Par exemple, pour <🎜. >, si ab est les deux S'il s'agit d'un non-stop non partagé, alors a sera classé en premier, mais si compareFlightPrice(a, b) est appelé, b sera classé en premier, il faut donc juger que a est un non-partagé non-stop et b n'est pas un non-stop non partagé, donc a est devant. compareFlightPrice(b, a)

Bien sûr, en plus de changer la fonction de comparaison, il existe une autre solution : ajouter des paramètres de démarrage à la jvm.

-Djava.util.Arrays.useLegacyMergeSort=true
Copier après la connexion
Il convient également de noter que cela ne signifie pas nécessairement qu'il y a des éléments égaux dans votre collection, et que la fonction de comparaison ne répond pas à la définition stricte ci-dessus, cette exception apparaîtra certainement de manière stable. , nous produisons La probabilité que cette exception se produise dans l'environnement est très faible. Après tout, Java n'est pas assez stupide pour vérifier d'abord l'ensemble du tableau. En fait, il constate que vous ne remplissez pas cette condition pendant le processus de tri. Il est donc possible qu'une sorte d'ordre de recouvrement vous permette simplement de contourner ce jugement.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Mar 17, 2025 pm 05:35 PM

Le chargement de classe de Java implique le chargement, la liaison et l'initialisation des classes à l'aide d'un système hiérarchique avec Bootstrap, Extension et Application Classloaders. Le modèle de délégation parent garantit que les classes de base sont chargées en premier, affectant la classe de classe personnalisée LOA

Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Mar 17, 2025 pm 05:44 PM

L'article examine la mise en œuvre de la mise en cache à plusieurs niveaux en Java à l'aide de la caféine et du cache de goyave pour améliorer les performances de l'application. Il couvre les avantages de configuration, d'intégration et de performance, ainsi que la gestion de la politique de configuration et d'expulsion le meilleur PRA

Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Mar 17, 2025 pm 05:43 PM

L'article discute de l'utilisation de JPA pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux. Il couvre la configuration, la cartographie des entités et les meilleures pratiques pour optimiser les performances tout en mettant en évidence les pièges potentiels. [159 caractères]

Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Mar 17, 2025 pm 05:46 PM

L'article discute de l'utilisation de Maven et Gradle pour la gestion de projet Java, la construction de l'automatisation et la résolution de dépendance, en comparant leurs approches et leurs stratégies d'optimisation.

Mar 17, 2025 pm 05:45 PM

L'article discute de la création et de l'utilisation de bibliothèques Java personnalisées (fichiers JAR) avec un versioning approprié et une gestion des dépendances, à l'aide d'outils comme Maven et Gradle.

See all articles