A TreeSet suporta dois métodos de classificação: classificação natural e classificação personalizada. O TreeSet usa classificação natural por padrão.
1. Classificação natural
O TreeSet chama o método Compareto (Object OBJ) do elemento de coleta para comparar a relação de tamanho entre os elementos e, em seguida, organiza os elementos de coleta em ordem crescente. (Presponse para comparação: os dois objetos têm o mesmo tipo).
O JAVA fornece uma interface comparável, que define um método Comparo (Object OBJ), que retorna um valor inteiro. Quando um objeto chama o método para comparar com outro objeto, por exemplo, obj1.comParto (Obj2), se o método retornar 0, significa que os dois objetos são iguais; obj2; se o método é retornado retornando um número inteiro negativo significa que obj1 é menor que obj2.
As classes Java comuns implementam interface comparável e fornecem padrões para tamanhos comparativos. Classes comuns que implementam interface comparável:
Se você tentar adicionar um objeto a um árvore, a classe do objeto deve implementar a interface comparável.
Um erro será relatado no seguinte programa:
classe err {} classe pública TestTreesError {public static void main (string [] args) {Treeset ts = new Treeset (); add (new err ());ilustrar:
O programa acima tenta adicionar 2 objetos de erro à coleção Treeset. do método do objeto) é comparado com outros elementos da coleção - se a classe correspondente não implementar a interface comparável, uma ClassCastException será aumentada. Além disso, ao tentar remover o primeiro elemento do elemento da árvore, uma exceção da ClassCastException ainda será aumentada.
Ao comparar objetos usando o método Compareto (Object OBJ), o tipo de objeto comparado que obj precisa ser fundido para o mesmo tipo, porque apenas duas instâncias da mesma classe podem comparar o tamanho. Ou seja, o objeto adicionado ao árvore deve ser da mesma classe, caso contrário, uma ClassCastException será levantada. Por exemplo, ao adicionar um objeto String a um árvore, esta operação é completamente normal. Ao adicionar o objeto da segunda data, o TreeSet chamará o método Compareto (Object Obj) do objeto para comparar com outros elementos da coleção, e o programa lançará uma exceção neste momento.
Na programação real, os programadores podem definir suas próprias classes para adicionar vários tipos de objetos ao TreeSet, desde que a classe definida pelo usuário implemente a interface comparável. Converta. No entanto, ao operar os dados de coleta em TreeSet, as exceções do ClassCastExceptio ainda ocorrerão para elementos de diferentes tipos. (Você entenderá depois de ler com cuidado)
Quando um objeto é adicionado à coleção TreeSet, o TreeSet chama o método Compareto (Object Obj) do objeto para comparar o tamanho com outros objetos no contêiner e, em seguida, determina seu local de armazenamento com base no algoritmo de árvore vermelha e preta. Se dois objetos forem comparados igualmente por compareto (objeto obj), o TreeSet os considera para armazenar o mesmo local.
Para as coleções de Treeset, o critério para determinar que dois objetos não são iguais é: dois objetos retornam false através da comparação de métodos iguais ou comparação compareto (object obj) não retorna 0 - mesmo se os dois objetos são o mesmo objeto, eles também será processado como dois objetos.
O programa a seguir mostra:
// A classe Z, reescreveu o método igual, sempre retorna falsa, // o método comparado (object obj), sempre retorna a classe Inteira positiva implementa {int age; } public boolean igual (objeto obj) {return false; Z z1 = novo z (6); set); Ver também se torna 9 system.out.println (((z) (set.last ()). Age);Resultados em execução do programa:
verdadeiro
[TRESET.Z@1FB8EE3, TRESET.Z@1FB8EE3]
9
ilustrar:
O mesmo objeto é adicionado duas vezes no programa, porque o método iguals () do objeto Z1 sempre retorna false, e o método compareto (object obj) sempre retorna 1. Dessa maneira, Treeset pensará que o objeto Z1 é diferente de si mesmo; portanto, adicione dois objetos Z1 ao The Treeset. Os dois elementos salvos pelo objeto Treeset são na verdade o mesmo elemento. Portanto, depois de modificar o atributo de idade do primeiro elemento na coleção Treeset, o atributo de idade do último elemento na coleção Treeset também muda.
Resumo : Quando você precisar colocar um objeto no TreeSet e reescrever o método Equals () da classe correspondente do objeto, você deve garantir que o método tenha resultados consistentes com o método CompareTo (Object Obj). Dois objetos passam quando a comparação do método igual retorna true, os dois objetos devem retornar 0 comparando o método compareto (object obj).
Se dois objetos forem comparados pelo método Equals, mas os dois objetos são comparados pelo método compareto (object obj) e não retornarão 0, isso fará com que Treeset salve os dois objetos em diferentes locais, para que ambos os objetos sejam ser adicionado com sucesso, o que é um pouco diferente das regras das coleções definidas.
Se dois objetos retornarem 0 comparando o método compareto (object obj), mas retornam falsos comparando o método igual: como os dois objetos são igualmente comparados com a comparação do método compareto (object obj), Treeset tentará salvá -los no O mesmo local, mas na verdade não funciona (caso contrário, restará apenas um objeto), por isso é mais problemático de lidar.
Se um objeto mutável for adicionado a uma árvore e o programa subsequente modifica as propriedades do objeto mutável, fazendo com que ele altere a ordem de tamanho com outros objetos, mas o Treeset não ajustará sua ordem novamente e pode até fazer com que seja salvo No TreeSet, esses dois objetos, eles retornam verdadeiros comparando o método Equals e o método compareto (object obj) retorna 0.
O programa a seguir mostra:
classe r {int contagem; if (obj instância r) {r r = (r) obj; classe TestHashSet2 {public static void main (string [] args) {hashset hs = new hashset (); R (9)); .Iterator (); em nenhum sistema de estado sequencial.println (hs); -3 r objeto? 5)));Resultados em execução do programa:
[R (atributo da contagem: -3), r (atributo da contagem: -2), r (atributo da contagem: 5), r (atributo da contagem: 9)]
[R (atributo da contagem: 20), r (atributo da contagem: -2), r (atributo da contagem: 5), r (atributo da contagem: -2)]
[R (atributo da contagem: 20), r (atributo da contagem: -2), r (atributo da contagem: 5), r (atributo da contagem: -2)]
[R (atributo da contagem: 20), r (atributo da contagem: -2), r (atributo da contagem: -2)]
ilustrar:
O objeto R no programa acima é uma reescrita normal do método igual e da classe de método comparável. Você pode ver que a primeira saída do programa está organizada de maneira ordenada. Quando a propriedade de contagem do objeto R é alterada, o resultado da saída do programa também muda e contém elementos duplicados. Uma vez que as propriedades dos elementos variáveis na coleção Treeset são alterados, quando o objeto é excluído na vista, o Treeset não é excluído (mesmo elementos originais na coleção não foram modificados, mas elementos iguais ao modificado elementos não podem ser excluídos).
Quando um objeto R com -2, nenhum elemento é excluído;
Resumo: Com o hashset, será muito complexo e propenso a erros ao lidar com esses objetos. Para tornar o programa mais robusto, é recomendável que apenas objetos imutáveis sejam colocados nas coleções de hashset e árvores.
2. Classificação personalizada
O tipo natural de trégua é baseado no tamanho dos elementos da coleção, e o Treeset os organiza em ordem crescente. Se você precisar implementar a classificação personalizada, como a ordem descendente, poderá usar a interface do comparador. Esta interface contém um método int compare (T O1, T O2), que é usado para comparar os tamanhos de O1 e O2.
Se você precisar implementar a classificação personalizada, precisará fornecer um objeto comparador ao criar um objeto de coleta de TreeSet e fornecer um objeto comparador para se associar à coleção TreeSet, e o objeto Comparador é responsável pela lógica de classificação dos elementos da coleção.
O programa a seguir mostra:
classe M {Int Age; main (string [] args) {TreeSet ts = new Treeset (new Comparator () {public int compare (objeto O1, objeto O2) {m m1 = (m) o1; m m2 = (m) o2; if (m1. idade> m2.age) {return -1; ts.add (novo m (-3));Resultados em execução do programa:
[M Objeto (idade: 9), M Objeto (Idade: 5), M Objeto (Idade: -3)]
ilustrar:
O programa acima cria um objeto de classe interna anônima da interface do comparador, responsável pela classificação da coleção TS. Portanto, quando adicionamos objetos M à coleção TS, não há necessidade de a classe M para implementar a interface comparável, porque neste momento, o TreeSet não precisa comparar o tamanho através dos objetos M, mas o objeto comparador associado ao TreeSet é responsável pela classificação dos elementos da coleção. Ao usar a classificação personalizada, o TreeSet classifica os elementos da coleção, independentemente do tamanho do próprio elemento de coleta, mas o objeto comparador é responsável pelas regras de classificação dos elementos de coleta.