Treeset prend en charge deux méthodes de tri: le tri naturel et le tri personnalisé. Treeset utilise le tri naturel par défaut.
1. Tri naturel
Treeset appellera la méthode compareto (objet OBJ) de l'élément de collecte pour comparer la relation de taille entre les éléments, puis organiser les éléments de collecte dans l'ordre croissant. (Presponse pour la comparaison: les deux objets ont le même type).
Java fournit une interface comparable, qui définit une méthode compareto (objet obj), qui renvoie une valeur entière. Lorsqu'un objet appelle la méthode à comparer avec un autre objet, par exemple obj1.comparto (obj2), si la méthode renvoie 0, cela signifie que les deux objets sont égaux; OBJ2; si la méthode est retournée, un entier négatif signifie que Obj1 est inférieur à l'OBJ2.
Les classes Java communes implémentent une interface comparable et fournissent des normes pour des tailles comparatives. Classes courantes qui implémentent une interface comparable:
Si vous essayez d'ajouter un objet à un arbre, la classe de l'objet doit implémenter l'interface comparable.
Une erreur sera signalée dans le programme suivant:
classe ERR {} classe publique TestTreeSeterror {public static void main (String [] args) {Treeset ts = new Treeset (); ajouter (new err ());}}illustrer:
Le programme ci-dessus essaie d'ajouter 2 objets ERR à la collection d'arbres. de l'objet) La méthode est comparée à d'autres éléments de la collection - si la classe correspondante n'implémente pas l'interface comparable, une classCastException sera augmentée. De plus, lorsque vous essayez de supprimer le premier élément de l'élément de l'arreset, une exception ClassCastException sera toujours augmentée.
Lorsque vous comparez des objets en utilisant la méthode compareto (objet OBJ), le type de l'objet comparé Obj doit être coulé au même type, car seuls deux instances de la même classe peuvent comparer la taille. Autrement dit, l'objet ajouté à l'arrestage devrait être de la même classe, sinon une classcastException sera soulevée. Par exemple, lors de l'ajout d'un objet de chaîne à un arbre, cette opération est complètement normale. Lors de l'ajout de l'objet de deuxième date, TreeSet appellera la méthode compareto (objet obj) de l'objet à comparer avec d'autres éléments de la collection, et le programme lancera une exception pour le moment.
Dans la programmation réelle, les programmeurs peuvent définir leurs propres classes pour ajouter plusieurs types d'objets à TreeSet, à condition que la classe définie par l'utilisateur implémente l'interface comparable. . Convertir. Cependant, lors de l'exploitation des données de collecte dans Treeset, des exceptions ClassCastExceptio se produiront toujours pour des éléments de différents types. (Vous comprendrez après avoir lu attentivement)
Lorsqu'un objet est ajouté à la collection Treeset, Treeset appelle la méthode compareto de l'objet (objet OBJ) pour comparer la taille avec d'autres objets du conteneur, puis détermine son emplacement de stockage en fonction de l'algorithme d'arbre rouge et noir. Si deux objets sont comparés de manière égale par compareto (objet OBJ), TreeSet les considère comme stockant le même emplacement.
Pour les collections de Treeset, le critère pour déterminer que deux objets ne sont pas égaux est: deux objets renvoient faux par la comparaison de la méthode égaux, ou comparaison compareto (objet obj) ne renvoie pas 0 - même si les deux objets sont le même objet, Treeset qu'ils sera également traité comme deux objets.
Le programme suivant montre:
// La classe Z, réécrite la méthode égale, renvoie toujours FAUX, // La méthode compareto (objet obj), renvoie toujours la classe entière positive Z implémente {int Age; public z (int Age) {this. } public boolean equals (objet obj) {return false;} public int compareto (objet obj) {return 1;}} public class testtreeSet {pub lic void main (String [] args) {arreset set = new Treeset (); Z Z1 = NOUVEAU Z (6); set); Voir aussi devient 9 System.out.println ((z) (set.last ()). Age);}}}Résultats du programme en cours d'exécution:
vrai
[Arreset.z@1fb8ee3, arreset.z@1fb8ee3]
9
illustrer:
Le même objet est ajouté deux fois dans le programme, car la méthode equals () de l'objet Z1 renvoie toujours FAUX, et la méthode compareto (objet obj) renvoie toujours 1. De cette façon, Treeset pensera que l'objet Z1 est différent de lui-même, alors ajoutez deux objets Z1 à l'arrestage. Les deux éléments enregistrés par l'objet Treeset sont en fait le même élément. Par conséquent, après avoir modifié l'attribut d'âge du premier élément de la collection d'arbres, l'attribut d'âge du dernier élément de la collection d'arbres change également.
Résumé : Lorsque vous devez mettre un objet dans Treeset et réécrire la méthode equals () de la classe correspondante de l'objet, vous devez vous assurer que la méthode a des résultats cohérents avec la méthode compareto (objet obj). Deux objets passent lorsque la comparaison de la méthode égaux renvoie true, les deux objets doivent retourner 0 en comparant la méthode compareto (objet obj).
Si deux objets sont comparés par la méthode égaux, mais que les deux objets sont comparés par la méthode CompareTo (objet obj) et ne renvoient pas 0, cela entraînera l'arrest Soyez ajouté avec succès, ce qui est un peu différent des règles des collections définies.
Si deux objets renvoient 0 en comparant la méthode compareto (objet obj), mais qu'elles retournent fausses en comparant la méthode égaux: parce que les deux objets sont également comparés à la comparaison de la méthode compareto (objet obj), Treeset essaiera de les enregistrer dans le Même emplacement, mais cela ne fonctionne pas en fait (sinon il ne restera qu'un seul objet), il est donc plus difficile à gérer.
Si un objet mutable est ajouté à un arbre et que le programme ultérieur modifie les propriétés de l'objet mutable, ce qui l'a fait modifier l'ordre de taille avec d'autres objets, mais le Treeset n'ajustera plus leur commande et peut même le faire enregistrer Dans le Treeset ces deux objets, ils renvoient vrai en comparant la méthode Equals, et la méthode compareto (objet obj) renvoie 0.
Le programme suivant montre:
classe r {int count; if (obj instance r) {r r = (r) obj; classe TestHashSet2 {public static void Main (String [] args) {HashSet HS = new HashSet (); R (9)); Hs.Add (nouveau R (-2)); .iTerator (); r premier = (r) it.next (); Dans aucun état séquentiel.out.println (HS); -3 r objet? 5)));}Résultats du programme en cours d'exécution:
[R (Count Attribut: -3), R (Count Attribut: -2), R (Count Attribut: 5), R (Count Attribut: 9)]
[R (Count Attribut: 20), R (Count Attribut: -2), R (Count Attribut: 5), R (Count Attribut: -2)]
[R (Count Attribut: 20), R (Count Attribut: -2), R (Count Attribut: 5), R (Count Attribut: -2)]
[R (Count Attribut: 20), R (Count Attribut: -2), R (Count Attribut: -2)]
illustrer:
L'objet R dans le programme ci-dessus est une réécriture normale de la méthode égale et de la classe de méthode comparable. Vous pouvez voir que la première sortie du programme est organisée de manière ordonnée. Lorsque la propriété Count de l'objet R est modifiée, le résultat de sortie du programme change également et contient des éléments en double. Une fois que les propriétés des éléments variables de la collection d'arbres sont modifiées, lorsque l'objet est supprimé dans la vue, Treeset ne parviendra pas à être supprimé (même les éléments originaux dans la collection n'ont pas été modifiés, mais les éléments qui sont égaux à la modification Les éléments ne peuvent pas être supprimés).
Lorsqu'un objet R avec -2, aucun élément n'est supprimé;
Résumé: Avec HashSet, il sera très complexe et sujette aux erreurs lors de la gestion de ces objets. Afin de rendre le programme plus robuste, il est recommandé que seuls les objets immuables soient placés dans les collections de hashset et d'arrestage.
2. Tri personnalisé
Le type naturel de Treeset est basé sur la taille des éléments de collecte, et Treeset les organise par ordre croissant. Si vous avez besoin d'implémenter le tri personnalisé, comme l'ordre descendant, vous pouvez utiliser l'interface du comparateur. Cette interface contient une méthode int compare (t o1, t o2), qui est utilisée pour comparer les tailles d'O1 et O2.
Si vous devez implémenter le tri personnalisé, vous devez fournir un objet de comparateur lors de la création d'un objet de collection d'arbres et fournir un objet de comparateur à associer à la collection d'arbres, et l'objet comparateur est responsable de la logique de tri des éléments de collecte.
Le programme suivant montre:
classe M {int Age; public m (int Age) {this.age = gence; main (String [] args) {arreset ts = new Treeset (new comparateur () {public int compare (objet o1, objet o2) {m m1 = (m) o1; m m2 = (m) o2; if (m1. Âge> M2.age) {return -1;} else if (m1.age == m2.age) {return 0;} else {return 1;}}); T.Add (new M (-3));Résultats du programme en cours d'exécution:
[M objet (âge: 9), M objet (âge: 5), M objet (âge: -3)]
illustrer:
Le programme ci-dessus crée un objet de classe interne anonyme de l'interface du comparateur, qui est responsable du tri de la collection TS. Ainsi, lorsque nous ajoutons des objets M à la collection TS, il n'est pas nécessaire que la classe M implémente l'interface comparable, car pour le moment, TreeSet n'a pas besoin de comparer la taille via les objets M, mais l'objet comparateur associé à Treeset est responsable du tri des éléments de collection. Lorsque vous utilisez le tri personnalisé, TreeSet trie les éléments de collecte quelle que soit la taille de l'élément de collecte lui-même, mais l'objet Comparateur est responsable des règles de tri des éléments de collecte.