[RESOLVIDO] Real necessidade do hashCode()?

Boa tarde pessoal, seguinte eu estou estudando a apostila de Algoritmo e Estrutura de Dados disponibilizada pela caelum, porem me deparei com a explicação do hashCode e surgiu uma duvida, segue abaixo a parte da explicação

equals e hashCode

Repare que a nossa busca pelo elemento usa o método contains da List. A implementação de lista que
estamos usando (assim como amaioria absoluta das coleções da API do Java) utiliza do método equals para
saber se determinado elemento está contido naquela lista ou não.
Um problema aparece quando rescrevemos o equals e não rescrevemos o hashCode: pode ser que existam
dois objetos, digamos a e b, que são considerados iguais pelo nosso método, mas possuem códigos de espalhamento
diferentes. Isto vai fazer com que a pesquisa por a, no caso de só existir b dentro do conjunto
retorne false, sendo que na verdade deveria retornar true pois estamos levando em consideração o que o
equals diz, e não o operador ==.

a explicação ficou clara, porem o que está descrito nunca acontece já que o hashCode utilizado é o native da classe Object, em outras palavras, implementei um exemplo do que está descrito e mesmo sem sobreescrever o hasCode() na minha entidade e o método contains() da ArrayList retorna true, pois o mesmo só usa o equals sobrescrito pela entidade.

Baseando-se nesse ponto o hashCode() sobrescrito serve somente para gerar um código hash(código de espalhamento) único para cada objeto?

que pode ser usado em estruturas de dados como HashSet ou HashMap, porem não interferem na comparação de objetos, certo?

pessoal por favor opinem e me corrijam se eu estiver errado, qualquer opinião é bem vinda, desde já agradeço.

http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode()

O contrato do hashcode é que dois objetos iguais (objA.equals(objB)) devem ter o mesmo hashcode (objA.hashCode() == objB.hashCode()).
Isso porque objetos que usam o hashcode, como HashSet ou HashMap, usam slots internos, como esse exemplo de Set…

hashCode 0 -> “a”, “b”
hashCode 1 -> “c”, “d”, “e”
hashCode 2 -> “f”

Sets não possuem objetos repetidos. Imagine que vc vai adicionar outro objeto no set acima. Vc vai adicionar um outro objeto “a”, mas que não possua o mesmo hashCode que o objeto “a” que já existe no Set. A primeira coisa que o set faz é achar o slot onde o novo objeto estaria. Imagine que o teu novo objeto tenha “hashCode 2”. O HashSet verá se existe outro objeto no slot “hashCode 2” que seja igual ao novo objeto “a”.
“hashCode 2” possui apenas o objeto “f”, portanto serial “legal” adicionar o objeto “a” neste slot. O resultado seria um Set como…

hashCode 0 -> “a”, “b”
hashCode 1 -> “c”, “d”, “e”
hashCode 2 -> “f”, “a”

Veja um exemplo desse problema…

public class TestMe {

    class MyObj {
        final String id;

        MyObj(String id) {
            this.id = id;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            MyObj myObj = (MyObj) o;

            if (id != null ? !id.equals(myObj.id) : myObj.id != null) return false;

            return true;
        }
    }


    @Test
    public void testMe() throws Exception {

        Set<MyObj> myObjs = new HashSet<MyObj>();
        myObjs.add(new MyObj("a"));
        myObjs.add(new MyObj("a"));
        Assert.assertEquals(1, myObjs.size());
    }
}
1 curtida