Prefacio
Cuando se refiere a la operación de comparación de comparar el "tamaño" de dos objetos al realizar algoritmos, como la clasificación de inserción, la clasificación de la colina y la clasificación de fusiones. Es fácil entender el método de comparación de Integer I> J, pero cuando clasificamos múltiples objetos, ¿cómo comparamos el "tamaño" de dos objetos? Tales comparaciones de Stu1> Stu2 son obviamente imposibles de compilar. Para resolver el problema de cómo comparar el tamaño de dos objetos, JDK proporciona dos interfaces java.lang.Comparable y java.util.Comparator .
1. Clasificación natural: java.lang.com PARA
Solo se proporciona un método en la interfaz comparable: compareTo(Object obj) , y el valor de retorno de este método es int. Si el valor de retorno es un número positivo, significa que el objeto actual (el objeto que llama al método) es "más grande" que el objeto OBJ; De lo contrario, es "pequeño"; Si es cero, significa que los dos objetos son iguales.
Aquí hay una clase de estudiante que implementa la interfaz comparable:
El estudiante de clase pública implementa comparable {private int id; nombre de cadena privada; estudiante público () {super (); } @Override public int Compareto (object obj) {if (obj instancia de alumno) {estudiante stu = (estudiante) obj; ID de retorno - stu.id; } return 0; } @Override public string toString () {return "<" + id + "," + nombre + ">"; }} El estudiante implementa la interfaz de clasificación natural comparable. Entonces, ¿cómo usamos esta interfaz para ordenar un conjunto de objetos de estudiantes? Cuando estábamos aprendiendo matrices, usamos una clase para ordenar las matrices enteras: java.util.Arrays . Utilizamos el método de clasificación de matrices para clasificar las matrices enteras. Después de pasar por la documentación de la API, encontrará que las matrices ofrecen muchas formas sobrecargadas del método de clasificación, incluida sort(Object[] obj) , lo que significa que Arryas también puede clasificar las matrices de objetos. Al comparar el "tamaño" de los dos objetos durante el proceso de clasificación, la interfaz comparable se utiliza para comparar el método Compareto.
Public Class Comparetest {public static void main (String [] args) {Student stu1 = new Student (1, "Little"); Estudiante stu2 = nuevo estudiante (2, "cyntin"); Estudiante stu3 = nuevo estudiante (3, "Tony"); Estudiante stu4 = nuevo estudiante (4, "Géminis"); Estudiante [] stus = nuevo estudiante [4]; stu0] = stu1; stu1 [1] = stu4; stus [2] = stu3; stu3] = stu2; System.out.println ("Array:" + Arrays.ToString (STUS)); Matrices.sort (stus); System.out.println ("Sort:" + Arrays.ToString (STUS)); }} El orden en que se agregan elementos en la matriz de estudiantes no se agrega de acuerdo con la identificación del estudiante. Después de llamar a Arrays.sort(stus) . No importa qué algoritmo de clasificación se utilice para implementarlo, definitivamente es necesario comparar la operación de "tamaño" de dos objetos. Entonces, ¿cómo se compara el "tamaño" de dos objetos? La interfaz comparable implementada por el estudiante entra en juego. El método de clasificación emitirá que el objeto se compare con comparable y llame al método Compareto para juzgar el "tamaño" de estos dos objetos en función de su valor de retorno. Por lo tanto, en este ejemplo, la matriz de estudiantes de estudiante original ordenada se convierte en una matriz de estudiantes ordenada por el número de estudiante.
Pero notamos que el algoritmo de clasificación está vinculado a la clase de estudiantes, y el estudiante solo tiene un algoritmo de clasificación. Pero este no es el caso en la sociedad real. ¿Qué pasa si no queremos ordenar por número de estudiante? ¿Qué pasa si queremos clasificar a los estudiantes por su nombre? Solo podemos modificar el método comparable de la interfaz comparable de la clase de estudiantes y cambiarlo para ordenar por nombre. ¿Qué pasa si hay dos operaciones en el mismo sistema, una está ordenada por el número de alumno y la otra se ordena por nombre? Es imposible escribir dos implementaciones de métodos comparados en el cuerpo de la clase de estudiantes. Desde este punto de vista, comparable tiene limitaciones. Para compensar esta deficiencia, JDK también nos proporciona otro método de clasificación, que es la clasificación de comparación de la que hablaremos a continuación.
2. Clasificación de comparación: java.util.comparador
Mencioné anteriormente que la razón por la cual se proporciona la interfaz de clasificación del comparador es que a veces es necesario ordenar el mismo objeto de muchas maneras diferentes, y esta clasificación natural comparable no se puede implementar. Además, una ventaja de la interfaz de comparación es que separa el algoritmo de clasificación de comparación de la clase de entidad específica.
Si mira a través de la API, encontrará que también hay una forma sobrecargada de matrices sort(T[] a, Comparator<? super T> c) El método utiliza genéricos para escribir parámetros de este método, que aún no hemos mencionado. Podemos entenderlo como esta forma: sort(Object[] a, Comparator c) , lo que significa clasificar la matriz de objetos de acuerdo con el algoritmo de clasificación de comparación dado por el Comparador C. Hay dos métodos definidos en la interfaz de comparación: compare(Object o1, Object o2) e equals los métodos. Dado que el método equals tiene métodos para todos los objetos, cuando implementamos la interfaz de comparación, solo necesitamos anular compare , en lugar de anular el método equals . La descripción del método igual al igual en la interfaz de comparación es: "Tenga en cuenta que siempre es seguro no anular Object.equals(Object) . Sin embargo, en algunos casos, anular este método puede permitir que el programa determine si dos comparadores diferentes forzan la misma clasificación, mejorando así el rendimiento". Solo necesitamos saber la primera oración y está bien. Es decir, no tenemos que pensar en cómo implementar el método igual, porque incluso si no mostramos la implementación del método igual, pero usamos el método igual de la clase de objeto, el código aún es seguro.
Así que escribamos un código para ordenarlo con un comparador. Todavía se realiza con la clase de estudiante, pero la interfaz comparable no se implementa. Dado que la clase de implementación del comparador solo usa la pantalla para implementar un método, no necesitamos escribir una clase para implementarla. Cuando necesitamos usar un comparador, podemos escribir una clase interna anónima para implementar un comparador.
Aquí está nuestro método de clasificación por nombre:
public void sortByName () {Student stu1 = New Student (1, "Little"); Estudiante stu2 = nuevo estudiante (2, "cyntin"); Estudiante stu3 = nuevo estudiante (3, "Tony"); Estudiante stu4 = nuevo estudiante (4, "Géminis"); Estudiante [] stus = nuevo estudiante [4]; stu0] = stu1; stu1; stu4; stu2] = stu3; stu3] = stu2; System.out.println ("Array:" + Arrays.ToString (STUS)); Arrays.sort (stus, new Comparator () {@Override public int Compare (Object O1, Object O2) {if (O1 InstanceOf Student && O2 Instalef Student) {Student S1 = (Student) O1; Student S2 = (Student) o2; // return s1.getid () - s2.getid (); // Arrange por identificación S1.getName (). Compareto (S2.getName ()); System.out.println ("Sorted:" + Arrays.ToString (STUS)); }Cuando necesitamos clasificar al estudiante por número de alumno, solo necesitamos modificar el código en la clase interna que implementa el comparador en nuestro método de clasificación, sin modificar la clase de estudiante.
Nota: Por supuesto, también puede usar la clase de estudiante para implementar la interfaz de comparación, de modo que el estudiante sea (es a) comparador (comparador). Cuando necesite usar este tipo, simplemente use el estudiante como comparador. Puede pasar al estudiante como parámetro en el método de clasificación porque el estudiante es un comparador. Pero dicho código no es un código excelente, porque una de las razones importantes por las que usamos Comparador es que puede separar el algoritmo de comparación de clases específicas y reducir el acoplamiento entre clases.
TreeSet proporciona apoyo para ambos métodos de comparación, correspondientes a los dos métodos de constructor de Treeset:
1. TreeSet (): Comparación y clasificación de acuerdo con el método Compareto de la interfaz comparable implementada por elementos en Treeset
2. Treeset (comparador de comparación): elementos de comparación y clasificación en Treeset de acuerdo con el comparador de comparación dado
Al agregar un elemento a un conjunto de árboles, el conjunto de árboles clasifica los elementos. En cuanto a si se debe ordenar con un orden natural o comparador, depende de cómo se escriba su construcción de su árbol. Por supuesto, no habrá comparación al agregar el primer elemento. No hay elementos en el árbol de árboles. ¿Con quién puedo comparar?
A continuación, se dan el código de prueba de TreeSet utilizando dos métodos de clasificación y comparación:
/ *** Usar el estudiante Natural Sort* debe implementar la interfaz comparable; de lo contrario, ClassCastException se arrojará*/ public void testSortedSet3 () {Student stu1 = new Student (1, "Little"); Estudiante stu2 = nuevo estudiante (2, "cyntin"); Estudiante stu3 = nuevo estudiante (3, "Tony"); Estudiante stu4 = nuevo estudiante (4, "Géminis"); Sortedset set = new TreeSet (); set.add (stu1); set.add (stu3); // Si el estudiante no implementa la interfaz comparable, tire ClassCastException set.add (stu4); set.add (stu2); set.add (stu4); set.add (nuevo estudiante (12, "pequeño")); System.out.println (set); } / *** Usar comparador para Sort* Student puede ser solo una clase Java simple sin implementar la interfaz comparable*/ public void testSortedSet3 () {Student stu1 = New Student (1, "Little"); Estudiante stu2 = nuevo estudiante (2, "cyntin"); Estudiante stu3 = nuevo estudiante (3, "Tony"); Estudiante stu4 = nuevo estudiante (4, "Géminis"); Sortedset set = new TreeSet (new Comparator () {@Override public int Compare (Object o1, Object o2) {if (O1 instanceOf student && o2 instancef student) {student s1 = (student) o1; student s2 = (student) o2; return s1.getName (). Comparación (s2.getName ());} return 0;}}); set.add (stu1); set.add (stu3); set.add (stu4); set.add (stu2); set.add (stu4); set.add (nuevo estudiante (12, "pequeño")); System.out.println (set); } Además, presente una clase de herramientas, java.util.Collections . Tenga en cuenta que esta no es una interfaz de colección. Las colecciones son muy similares a la clase de matrices. Arrays proporciona una serie de métodos estáticos para operaciones de matriz, clasificación de búsqueda y más. Las colecciones también proporcionan una serie de tales métodos, pero se utiliza para procesar colecciones. Aunque la clase de colecciones es muy similar a la interfaz de colecciones, no se deje engañar por el nombre de las colecciones. No es una clase de implementación que solo puede manejar la interfaz de colección y las subinterfaces, sino que también puede manejar la clase de implementación de la interfaz de mapa.
Resumir
Este es el final de la introducción a la clasificación natural y la clasificación del comparador en Java. El artículo sigue siendo relativamente detallado. Espero que pueda ayudarlo en su estudio o trabajo. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse.