Prefácio
Quando se refere à operação de comparação de comparar o "tamanho" de dois objetos ao executar algoritmos como classificação de inserção, tipo de colina e classificação de mesclagem. É fácil entender o método de comparação de número inteiro, mas quando classificamos vários objetos, como comparamos o "tamanho" de dois objetos? Tais comparações de Stu1> Stu2 são obviamente impossíveis de compilar. Para resolver o problema de como comparar o tamanho de dois objetos, o JDK fornece duas interfaces java.lang.Comparable e java.util.Comparator .
1. Classificação natural: java.lang.comparable
Existe apenas um método fornecido na interface comparável: compareTo(Object obj) , e o valor de retorno desse método é int. Se o valor de retorno for um número positivo, significa que o objeto atual (o objeto que chama o método) é "maior" que o objeto OBJ; Caso contrário, é "pequeno"; Se for zero, significa que os dois objetos são iguais.
Aqui está uma aula de estudante que implementa a interface comparável:
A classe pública Student implementa comparável {private int id; nome de string privado; public student () {super (); } @Override public int compareto (object obj) {if (obj instanceof student) {Student stu = (student) obj; Retornar ID - Stu.id; } retornar 0; } @Override public string tostring () {return "<" + id + "," + nome + ">"; }} O aluno implementa a interface de classificação natural comparável. Então, como usamos essa interface para classificar um conjunto de objetos do aluno? Quando estávamos aprendendo matrizes, usamos uma aula para classificar as matrizes inteiras: java.util.Arrays . Usamos o método de classificação das matrizes para classificar as matrizes inteiras. Depois de folhear a documentação da API, você descobrirá que as matrizes fornecem muitas formas sobrecarregadas do método de classificação, incluindo sort(Object[] obj) , o que significa que as arryas também podem classificar as matrizes de objetos. Ao comparar o "tamanho" dos dois objetos durante o processo de classificação, a interface comparável é usada para comparar o método compareto.
classe pública comparetest {public static void main (string [] args) {Student stu1 = novo aluno (1, "Little"); Estudante stu2 = novo aluno (2, "cyntin"); Estudante stu3 = novo aluno (3, "Tony"); Estudante stu4 = novo aluno (4, "gemini"); Aluno [] STUS = novo aluno [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)); }} A ordem em que os elementos são adicionados na matriz do aluno não é adicionado de acordo com o ID do aluno. Depois de ligar para Arrays.sort(stus) , classifique a matriz do aluno. Independentemente do algoritmo de tipo que é usado para implementá -lo, é definitivamente necessário comparar a operação de "tamanho" de dois objetos. Então, como você compara o "tamanho" de dois objetos? A interface comparável implementada pelo aluno entra em jogo. O método de classificação lançará o objeto a ser comparado a comparável e chamará o método compareto para julgar o "tamanho" desses dois objetos com base em seu valor de retorno. Portanto, neste exemplo, a matriz fora de ordem original classificada se torna uma matriz de estudantes classificada pelo número do aluno.
Mas percebemos que o algoritmo de classificação está vinculado à aula de estudante e o aluno possui apenas um algoritmo de classificação. Mas esse não é o caso na sociedade real. E se não queremos classificar pelo número do aluno? E se quisermos classificar os alunos pelo nome? Só podemos modificar o método compareto da interface comparável da aula do aluno e alterá -lo para classificar pelo nome. E se houver duas operações no mesmo sistema, uma é classificada pelo número do aluno e o outro é classificado pelo nome? É impossível escrever duas implementações de métodos compareto no corpo da classe estudantil. Desse ponto de vista, comparável tem limitações. Para compensar essa falha, o JDK também nos fornece outro método de classificação, que é a classificação do comparador que falaremos abaixo.
2. Classificação do comparador: java.util.comparator
Mencionei acima que a razão pela qual a interface de classificação do comparador é fornecida é que, às vezes, é necessário classificar o mesmo objeto de muitas maneiras diferentes, e essa classificação natural comparável não pode ser implementada. Além disso, uma vantagem da interface do comparador é que ela separa o algoritmo de classificação de comparação da classe de entidade específica.
Se você olhar através da API, descobrirá que também há uma forma sobrecarregada de Arrays.Sort: sort(T[] a, Comparator<? super T> c) . O método usa genéricos para escrever parâmetros desse método, que ainda não mencionamos. Podemos entendê -lo como este formulário: sort(Object[] a, Comparator c) , o que significa classificar a matriz de objetos de acordo com o algoritmo de classificação de comparação dado pelo comparador c. Existem dois métodos definidos na interface do comparador: compare(Object o1, Object o2) e equals a métodos. Como o método equals possui métodos para todos os objetos, quando implementamos a interface do comparador, precisamos apenas substituir compare , em vez de substituir o método equals . A descrição do método de substituição é igual na interface do comparador é: "Observe que é sempre seguro não substituir Object.equals(Object) . Só precisamos conhecer a primeira frase e está tudo bem. Ou seja, não precisamos pensar em como implementar o método Equals, porque mesmo que não mostre a implementação do método igual, mas use o método igual da classe de objeto, o código ainda é seguro.
Então, vamos escrever um código para classificá -lo com um comparador. Ainda está feito com a aula do aluno, mas a interface comparável não é implementada. Como a classe de implementação do comparador usa apenas a exibição para implementar um método, não podemos escrever uma classe para implementá -la. Quando precisamos usar um comparador, podemos escrever uma classe interna anônima para implementar o comparador.
Aqui está o nosso método de classificação pelo nome:
public void SortbyName () {Student Stu1 = New Student (1, "Little"); Estudante stu2 = novo aluno (2, "cyntin"); Estudante stu3 = novo aluno (3, "Tony"); Estudante stu4 = novo aluno (4, "gemini"); Aluno [] STUS = novo aluno [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 (objeto O1, objeto O2) {if (o1 instância do aluno && o2 Instância do aluno) {Student S1 = (Student) O1; Student S2 = (Student) o2; // Return S1.getId () - S2.getId () //rganize () O2; s1.getName (). Compareto (s2.getName ()); System.out.println ("classificado:" + Arrays.toString (sTus)); }Quando precisamos classificar o número do aluno pelo aluno, apenas precisamos modificar o código na classe interna que implementa o comparador em nosso método de classificação, sem modificar a classe do aluno.
NOTA: Obviamente, você também pode usar a aula do aluno para implementar a interface do comparador, para que o aluno seja (é um) comparador (comparador). Quando você precisar usar esse tipo, basta usar o aluno como comparador. Você pode passar o aluno como um parâmetro no método de classificação porque o aluno é um comparador. Mas esse código não é um excelente código, porque uma das razões importantes pelas quais usamos o comparador é que ele pode separar o algoritmo de comparação de classes específicas e reduzir o acoplamento entre as classes.
O TreeSet fornece suporte para ambos os métodos de comparação, correspondendo aos dois métodos construtores de TreeSet:
1. TreeSet (): Comparação e classificação de acordo com o método compareto da interface comparável implementada por elementos em TreeSet
2. Treeset (comparador comparador): Comparação e classificação elementos em Treeset de acordo com o comparador do comparador fornecido
Ao adicionar um elemento a um árvore, o treeset classifica os elementos. Quanto a classificar com a ordem ou comparador natural, depende de como o seu construto TreeSet está escrito. Obviamente, não haverá comparação ao adicionar o primeiro elemento. Não há elementos no árvore. Com quem posso comparar?
Abaixo, são fornecidos o código de teste de Treeset usando dois métodos de classificação e comparação:
/ *** Use a classificação natural* O aluno deve implementar a interface comparável, caso contrário, a ClassCastException será lançada*/ public void testSortEdSet3 () {Student Stu1 = novo aluno (1, "Little"); Estudante stu2 = novo aluno (2, "cyntin"); Estudante stu3 = novo aluno (3, "Tony"); Estudante stu4 = novo aluno (4, "gemini"); Set storedSet = new TreeSet (); set.add (STU1); set.add (STU3); // Se o aluno não implementar a interface comparável, jogue o ClassCastException set.add (STU4); set.add (STU2); set.add (STU4); set.add (novo aluno (12, "Little")); System.out.println (set); } / *** Use o comparador para classificar* o aluno pode ser apenas uma classe Java simples sem implementar a interface comparável*/ public void testSortEdSet3 () {Student stu1 = novo aluno (1, "Little"); Estudante stu2 = novo aluno (2, "cyntin"); Estudante stu3 = novo aluno (3, "Tony"); Estudante stu4 = novo aluno (4, "gemini"); SetEdSet SET = new TreeSet (new Comparator () {@Override public int compare (objeto o1, objeto o2) {if (o1 instância do aluno && o2 Instância do aluno) {Student s1 = (Student) o1; Student S2 = (Student) O2; Return S1.getName (). set.add (STU1); set.add (STU3); set.add (STU4); set.add (STU2); set.add (STU4); set.add (novo aluno (12, "Little")); System.out.println (set); } Além disso, introduza uma classe de ferramentas, java.util.Collections . Observe que isso não é uma interface de coleção. As coleções são muito semelhantes à aula de matrizes. A Arrays fornece uma série de métodos estáticos para operações de matriz, encontrar classificação e muito mais. As coleções também fornecem uma série desses métodos, mas são usados para processar coleções. Embora a classe de coleções seja muito semelhante à interface de coleções, não se deixe enganar pelo nome das coleções. Não é uma classe de implementação que só pode lidar com a interface de coleta e sub-interfaces, mas também pode lidar com a classe de implementação da interface do mapa.
Resumir
Este é o fim da introdução à classificação natural e à classificação do comparador em Java. O artigo ainda é relativamente detalhado. Espero que possa ajudá -lo em seu estudo ou trabalho. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar.