[SCJP] dúvida hashCode() e equals

Uma implementação possível do hashSet é um array de listas.

Imagine que cada índice do array são as gavetas de cores, que nosso colega falou. E as listas, é o espaço da gaveta, onde você pode colocar as meias.

Pois bem, se você não implementar o hashCode, o java utilizará a implementação padrão. Essa implementação usa o endereço de memória do objeto para dizer seu hash. Ou seja, dois objetos, usando esse algoritmo, jamais terão o mesmo hashCode. Portanto, é como se todas as suas meias tivessem cores diferentes. Essa é a mesma política adotada para o equals, portanto, esses métodos estão consistentes, mesmo com sua implementação padrão. Ou seja, para a implementação padrão, com objetos diferentes, você nunca precisará testar se uma meia é igual a outra, pois, nessa implementação, você tem exatamente uma gaveta por meia. Você pode fazer com que o método equals seja chamado, basta inserir 2 vezes o mesmo objeto no set.

Quando você implementa o equals, você está alterando a definição de igualdade. Você está dizendo que dois objetos de endereço de memória diferentes podem, eventualmente, ser considerados iguais. Portanto, é necessário também fornecer um hash que indique que eles sejam iguais. O hash é um número, e serve como um atalho para definir se dois objetos são ou não iguais.

Entretanto, o contrário não é verdadeiro. Dois objetos de mesmo hash podem, eventualmente, não serem iguais. O hash é um atalho, o equals é o método que realmente distingue um objeto de outro. Como um HashSet não permite duplicatas, como ele fará para não descartar objetos de mesmo hash que sejam diferentes? É aí que entra a regra que o colega tentou te explicar. Sempre que ele encontra um hash igual, ele irá comparar se o objeto encontrado lá é mesmo igual ao objeto recebido. Se for igual, o objeto será substituido pelo passado. Se for diferente, o objeto será colocado na mesma posição do hashmap, no próximo índice livre da lista.

Um exemplo de caso de hashs iguais são as Strings “auréola” e “desprezível”, como bem citado pelo Thingol. Obseve que a mesma estratégia de combinar hash com equals é também usada no switch do Java 7, como ele explica nesse post:

1 curtida

[quote=ViniGodoy]Uma implementação possível do hashSet é um array de listas.

Imagine que cada índice do array são as gavetas de cores, que nosso colega falou. E as listas, é o espaço da gaveta, onde você pode colocar as meias.

Pois bem, se você não implementar o hashCode, o java utilizará a implementação padrão. Essa implementação usa o endereço de memória do objeto para dizer seu hash. Ou seja, dois objetos, usando esse algoritmo, jamais terão o mesmo hashCode. Portanto, é como se todas as suas meias tivessem cores diferentes. Essa é a mesma política adotada para o equals, portanto, esses métodos estão consistentes, mesmo com sua implementação padrão. Ou seja, para a implementação padrão, com objetos diferentes, você nunca precisará testar se uma meia é igual a outra, pois, nessa implementação, você tem exatamente uma gaveta por meia. Você pode fazer com que o método equals seja chamado, basta inserir 2 vezes o mesmo objeto no set.

Quando você implementa o equals, você está alterando a definição de igualdade. Você está dizendo que dois objetos de endereço de memória diferentes podem, eventualmente, ser considerados iguais. Portanto, é necessário também fornecer um hash que indique que eles sejam iguais. O hash é um número, e serve como um atalho para definir se dois objetos são ou não iguais.

Entretanto, o contrário não é verdadeiro. Dois objetos de mesmo hash podem, eventualmente, não serem iguais. O hash é um atalho, o equals é o método que realmente distingue um objeto de outro. Como um HashSet não permite duplicatas, como ele fará para não descartar objetos de mesmo hash que sejam diferentes? É aí que entra a regra que o colega tentou te explicar. Sempre que ele encontra um hash igual, ele irá comparar se o objeto encontrado lá é mesmo igual ao objeto recebido. Se for igual, o objeto será substituido pelo passado. Se for diferente, o objeto será colocado na mesma posição do hashmap, no próximo índice livre da lista.

Um exemplo de caso de hashs iguais são as Strings “auréola” e “desprezível”, como bem citado pelo Thingol. Obseve que a mesma estratégia de combinar hash com equals é também usada no switch do Java 7, como ele explica nesse post:
http://thingol-guj.blogspot.com/2010/03/switch-com-strings-no-java-7.html[/quote]

Valeu Vini .

Re-lembrei toda essa parte de HashCode e Equals com a sua resposta . abs

1 curtida

Ótima discussão, estava com dificuldades para entender o funcionamento dos métodos equals/hashcode, agora ficou claro, vlw galera :slight_smile:

rogelGarcia, cara parabéns pela explicação, estou estudando para certificação, e estava aqui a procurar uma explicação para uma questão do mock, e vi sua ultima explicação show de bola!

ficou assim.

 public boolean equals(Object obj) {  
    if (this.clube == obj) {  
        return true;  
    }else{
        return false;
    }
}
public class Teste{
      
        
      public static void main(String[] args) {  
        HashSet<Partida> partidas = new HashSet<Partida>();  
          
        partidas.add(new Partida("Palmeiras", "Santos" , "Palestra" , 2, 1)); 
         partidas.add(new Partida("Palmeiras", "Santos" , "Palestra" , 2, 1));  
                  
  
        System.out.println(partidas.equals(partidas));  
    }  
} 

e como eu faço a outra parte?

Sua pergunta está incompleta, como eu faço a outra parte???

Primeiro seu equals está “estranho”, esta considerando o mesmo endereço de memória do objeto clube, acredito que o equals já está meio estranho, pois deveria considerar o “nome” do clube, depois você está usando o objeto Partida dentro da coleção…

Tente definir melhor o que quer.