Préface
Lorsqu'il fait référence à l'opération de comparaison de la comparaison de la "taille" de deux objets lors de la réalisation d'algorithmes tels que le tri d'insertion, le tri des collines et la fusion. Il est facile de comprendre la méthode de comparaison de Integer i> j, mais lorsque nous trierons plusieurs objets, comment comparer la "taille" de deux objets? De telles comparaisons de Stu1> Stu2 sont évidemment impossibles à compiler. Pour résoudre le problème de la façon de comparer la taille de deux objets, JDK fournit deux interfaces java.lang.Comparable et java.util.Comparator .
1. Tri naturel: java.lang.comparable
Il n'y a qu'une seule méthode fournie dans l'interface comparable: compareTo(Object obj) , et la valeur de retour de cette méthode est int. Si la valeur de retour est un nombre positif, cela signifie que l'objet actuel (l'objet qui appelle la méthode) est "plus grand" que l'objet OBJ; Sinon, c'est "petit"; S'il est nul, cela signifie que les deux objets sont égaux.
Voici une classe étudiante qui implémente l'interface comparable:
classe publique étudiant implémente comparable {private int id; nom de chaîne privé; Student public () {super (); } @Override public int compareto (objet obj) {if (obj instanceof student) {Student Stu = (Student) obj; ID de retour - Stu.id; } return 0; } @Override public String toString () {return "<" + id + "," + name + ">"; }} L'élève implémente l'interface de tri naturelle comparable. Alors, comment utilisons-nous cette interface pour trier un ensemble d'objets étudiants? Lorsque nous apprenions des tableaux, nous avons utilisé une classe pour trier les tableaux entiers: java.util.Arrays . Nous utilisons la méthode de tri de Arrays pour trier les tableaux entiers. Après avoir traversé la documentation de l'API, vous constaterez que les tableaux donnent de nombreuses formes surchargées de la méthode de tri, y compris sort(Object[] obj) , ce qui signifie que Arryas peut également trier les tableaux d'objets. Lors de la comparaison de la "taille" des deux objets pendant le processus de tri, l'interface comparable est utilisée pour comparer la méthode compareto.
classe publique CompareTest {public static void main (String [] args) {étudiant Stu1 = new Student (1, "Little"); Student Stu2 = New Student (2, "Cyntin"); Student Stu3 = New Student (3, "Tony"); Student Stu4 = nouvel étudiant (4, "Gemini"); Étudiant [] STUS = nouvel étudiant [4]; Stu0] = Stu1; Stu1 [1] = Stu4; STUS [2] = Stu3; Stu3] = Stu2; System.out.println ("Array:" + Arrays.ToString (STUS)); Arrays.sort (STUS); System.out.println ("Sort:" + Arrays.ToString (STUS)); }} L'ordre dans lequel des éléments sont ajoutés dans le tableau d'étudiant n'est pas ajouté en fonction de l'identification des étudiants. Après avoir appelé Arrays.sort(stus) , triez le tableau des étudiants. Peu importe quel algorithme de tri est utilisé pour l'implémenter, il est certainement nécessaire de comparer le fonctionnement "taille" de deux objets. Alors, comment comparez-vous la "taille" de deux objets? L'interface comparable implémentée par Student entre en jeu. La méthode de tri mettra l'objet à comparer à comparable et appellera la méthode compareto pour juger la "taille" de ces deux objets en fonction de sa valeur de retour. Par conséquent, dans cet exemple, le tableau d'origine des étudiants hors service triée devient un tableau d'étudiant trié par numéro d'étudiant.
Mais nous avons remarqué que l'algorithme de tri est lié à la classe étudiante et que l'élève n'a qu'un seul algorithme de tri. Mais ce n'est pas le cas dans la vraie société. Et si nous ne voulons pas trier par numéro d'étudiant? Et si nous voulons trier les étudiants par leur nom? Nous ne pouvons modifier que la méthode compareto de l'interface comparable de la classe étudiante et la modifier en trier par son nom. Et s'il y a deux opérations dans le même système, l'une est triée par numéro d'étudiant et l'autre est triée par son nom? Il est impossible d'écrire deux implémentations de méthodes de comparaison dans le corps de la classe étudiante. De ce point de vue, comparable a des limites. Afin de compenser cette lacune, JDK nous fournit également une autre méthode de tri, qui est le tri du comparateur dont nous parlerons ci-dessous.
2. Tri du comparateur: java.util.comparateur
J'ai mentionné ci-dessus que la raison pour laquelle l'interface de tri du comparateur est fournie est qu'il est parfois nécessaire de trier le même objet de différentes manières, et ce tri naturel comparable ne peut pas être mis en œuvre. De plus, un avantage de l'interface du comparateur est qu'il sépare l'algorithme de tri de comparaison de la classe d'entité spécifique.
Si vous regardez à travers l'API, vous constaterez qu'il existe également une forme surchargée de tableaux.Sort: sort(T[] a, Comparator<? super T> c) . La méthode utilise des génériques pour écrire des paramètres de cette méthode, que nous n'avons pas encore mentionnés. Nous pouvons le comprendre comme cette forme: sort(Object[] a, Comparator c) , ce qui signifie tri le tableau d'objet en fonction de l'algorithme de tri de comparaison donné par le comparateur c. Il existe deux méthodes définies dans l'interface du comparateur: compare(Object o1, Object o2) et equals aux méthodes. Étant donné que la méthode equals a des méthodes pour tous les objets, lorsque nous implémentons l'interface du comparateur, nous avons seulement besoin de remplacer compare , au lieu de remplacer la méthode equals . La description de la mise en œuvre égale à la méthode dans l'interface du comparateur est: "Notez qu'il est toujours sûr de ne pas écraser Object.equals(Object) . Nous avons seulement besoin de connaître la première phrase et c'est OK. C'est-à-dire que nous n'avons pas à réfléchir à la façon d'implémenter la méthode Equals, car même si nous ne montrons pas l'implémentation de la méthode Equals, mais utilisons la méthode Equal de la classe d'objets, le code est toujours sûr.
Écrivons donc un code pour le trier avec un comparateur. Cela se fait toujours avec la classe étudiante, mais l'interface comparable n'est pas mise en œuvre. Étant donné que la classe d'implémentation du comparateur utilise uniquement l'affichage pour implémenter une méthode, nous ne pouvons pas avoir besoin d'écrire de classe pour l'implémenter. Lorsque nous devons utiliser un comparateur, nous pouvons écrire une classe interne anonyme pour implémenter le comparateur.
Voici notre méthode de tri par son nom:
public void sortByName () {étudiant Stu1 = nouvel étudiant (1, "petit"); Student Stu2 = New Student (2, "Cyntin"); Student Stu3 = New Student (3, "Tony"); Student Stu4 = nouvel étudiant (4, "Gemini"); Étudiant [] STUS = nouvel étudiant [4]; Stu0] = Stu1; Stu1; Stu4; Stu2] = Stu3; Stu3] = Stu2; System.out.println ("Array:" + Arrays.ToString (STUS)); Arrays.sort (Stus, nouveau comparateur () {@Override public int compare (objet o1, objet o2) {if (o1 instanceof étudiant && o2 instanceof student) {student s1 = (étudiant) o1; étudiant s2 = (étudiant) o2; // return s1.getid () - s2.getid (); // arrange by id return s1.getid () - s2.getid (); // arrange by id rendement s1.getName (). Compareto (s2.GetName ()); System.out.println ("tri:" + arrays.tostring (SUT)); }Lorsque nous devons trier l'élève par numéro d'élève, nous avons juste besoin de modifier le code dans la classe intérieure qui implémente le comparateur dans notre méthode de tri, sans modifier la classe étudiante.
Remarque: Bien sûr, vous pouvez également utiliser la classe étudiante pour implémenter l'interface du comparateur, afin que l'élève soit (est a) Comparateur (comparateur). Lorsque vous devez utiliser ce type, utilisez simplement Student comme comparateur. Vous pouvez passer l'élève comme paramètre dans la méthode de tri car l'élève est un comparateur. Mais un tel code n'est pas un excellent code, car l'une des raisons importantes pour lesquelles nous utilisons le comparateur est qu'il peut séparer l'algorithme de comparaison des classes spécifiques et réduire le couplage entre les classes.
Treeset fournit un support pour les deux méthodes de comparaison, correspondant aux deux méthodes de constructeur de Treeset:
1.
2.
Lors de l'ajout d'un élément à un arbre, l'arbre trie les éléments. Quant à la trier avec l'ordre ou le comparateur naturel, cela dépend de la façon dont votre construction d'arbres est écrite. Bien sûr, il n'y aura pas de comparaison lors de l'ajout du premier élément. Il n'y a pas d'éléments dans le Treeset. Avec qui puis-je comparer?
Ci-dessous, le code de test d'arbres à l'aide de deux méthodes de tri et de comparaison est donnée:
/ ** * UTILISER NATUREL SORT * Student doit implémenter l'interface comparable, sinon ClassCastException sera lancée * / public void testSortEdSet3 () {Student Stu1 = New Student (1, "Little"); Student Stu2 = New Student (2, "Cyntin"); Student Stu3 = New Student (3, "Tony"); Student Stu4 = nouvel étudiant (4, "Gemini"); SORDSET Set = new TreeSet (); set.add (Stu1); set.add (Stu3); // Si l'élève n'implémente pas l'interface comparable, lancez classCastException set.add (STU4); set.add (Stu2); set.add (Stu4); set.add (nouveau étudiant (12, "Little")); System.out.println (set); } / ** * Utilisez le comparateur pour trier * L'élève peut être juste une simple classe Java sans implémenter l'interface comparable * / public void testSortEdSet3 () {Student Stu1 = new Student (1, "Little"); Student Stu2 = New Student (2, "Cyntin"); Student Stu3 = New Student (3, "Tony"); Student Stu4 = nouvel étudiant (4, "Gemini"); TridSet set = new TreeSet (nouveau comparateur () {@Override public int compare (objet o1, objet o2) {if (o1 instanceof student && o2 instanceof student) {student s1 = (student) o1; student s2 = (student) o2; return s1.getName (). Competo (s2.getName ());} return 0;}}); set.add (Stu1); set.add (Stu3); set.add (Stu4); set.add (Stu2); set.add (Stu4); set.add (nouveau étudiant (12, "Little")); System.out.println (set); } De plus, introduisez une classe d'outils, java.util.Collections . Notez qu'il ne s'agit pas d'une interface de collection. Les collections sont très similaires à la classe des tableaux. Arrays fournit une série de méthodes statiques pour les opérations de tableau, le tri de recherche, et plus encore. Les collections fournissent également une série de ces méthodes, mais elle est utilisée pour traiter les collections. Bien que la classe de collections soit très similaire à l'interface de collections, ne vous laissez pas berner par le nom des collections. Ce n'est pas une classe d'implémentation qui ne peut gérer que l'interface de collecte et les sous-interfaces, mais peut également gérer la classe d'implémentation de l'interface MAP.
Résumer
Ceci est la fin de l'introduction au tri naturel et au tri du comparateur en Java. L'article est encore relativement détaillé. J'espère que cela peut vous aider dans votre étude ou votre travail. Si vous avez des questions, vous pouvez laisser un message pour communiquer.