What is the importance of implementing the hashcode method in Java?

Asked

Viewed 13,799 times

27

  1. How important it is to implement the hashcode method in Java?

  2. How the hashcode method differentiates two objects?

1 answer

29


The hashCode() is used for objects of the type Collection organize its elements, for example, in an academy that has the student cards separated by the first letter of the student name, those abinhas A, B, C, ... inside a folder or document holder (ok, today it’s all via systems, but everyone remembers the paper chips, does not remember?).

This makes it easier to find a student’s name among so many. If you want to find the student John you first get everyone who starts with the letter J and then you search within the possibilities the exact name you need, the number plate, etc., instead of searching among all students enrolled in the academy.

Searching the tab with the first letter of the student’s name would be equivalent to searching by hashCode(), search for the student’s exact name would be equivalent to the search for equals().

Let’s take an example, imagine the Product class below with the hashCode() and the equals() implemented:

public class Produto {
    int idProduto;
    String nomeProduto;

    public Produto(int idProduto, String nomeProduto) {
        super();
        this.idProduto = idProduto;
        this.nomeProduto = nomeProduto;
    }

    //getters and setters aqui!

    @Override
    public int hashCode() {
        //deve ser o mesmo resultado para um mesmo objeto, não pode ser aleatório
        return this.idProduto;
    }

    @Override
    public boolean equals(Object obj) {
        //se nao forem objetos da mesma classe sao objetos diferentes
        if(!(obj instanceof Produto)) return false; 

        //se forem o mesmo objeto, retorna true
        if(obj == this) return true;

        // aqui o cast é seguro por causa do teste feito acima
        Produto produto = (Produto) obj; 

        //aqui você compara a seu gosto, o ideal é comparar atributo por atributo
        return this.idProduto == produto.getIdProduto() &&
                this.nomeProduto.equals(produto.getNomeProduto());
    }   
}

Now suppose we wish to create an object of the Collection type, say, a HashSet<>(), and store a list of various Product-type objects:

public class TesteCollection {
    public static void main(String[] args) {
        Set<Produto> produtos = new HashSet<>();

        produtos.add(new Produto(1, "Caderno 96 folhas"));
        produtos.add(new Produto(2, "Lapis 2B"));
        produtos.add(new Produto(3, "Borracha"));
        produtos.add(new Produto(4, "Estojo"));

        //em algum ponto do programa que você não possui mais
        //a variável de referência para o objeto que você quer
        //encontrar na lista
        Produto p = new Produto(4, "Estojo");
        System.out.println(produtos.contains(p));
    }
}

In the method contains(), the set needs seek out the product in its product collection, the method returns true or false informing you whether or not you have found it. You call the method by passing a reference variable of the Product type and ask if this product is contained in the set, however, how you had to create a new object (note the word new in the top row) that new object IS NOT in the set, what you have at that point is a new object, and it may be that there is an object within the set that has the same identifier attributes (the attributes that you considered relevant and placed within your equals()), usually this is what we need, a new object with identical identifier attributes and not the actual object within the collection.

In the contains() the list first takes all objects within your collection that have the same hashCode(), then it searches among all found objects which is equal according to the implementation of the equals(), in the above example, the return is true.

EDIT

The hashcode groups objects according to a precondition, such as the form of students that groups students by letter?

Yes, collections group objects that have exactly the same hashCode().

It is used to compare objects within collections?

It is not used to compare, but is used to find objects within the collection, because first the group to which the object belongs is searched then the object is searched by comparing objects, so if it is not possible to find the group it will not be possible to find the object. The comparison of objects is done through the result of the method equals().

The implementation correct of hashCode() is the one that always returns the same value when called to the same object, according to the hashcode agreement().

In addition to correctly implementing should always seek to implement the hashCode() efficiently. When implemented in an efficient way it helps the collections to eliminate various objects that are certainly not what is being sought, ie it discards the groups of objects that do not produce certain hashCode().

An example of implementation of hashCode() inefficient:

public int hashCode() { return 42; } //é válido, porém ineficiente

It is inefficient because all objects will be in the same group, making the work of the collection difficult when looking for an object. The most efficient way to implement is if you can ensure a way to generate hashCode()unique s for each object, so you will be ensuring that there will be only one object per group of hashCode() within the collection.

  • Math, very good explanation. However, it was not clear to me how the hashcode works. The equals, as your example explained, compares two objects by the value contained in their attributes. And how does the hashcode work? You can add an example of this in your reply?

  • Don’t you understand which part? What should be the implementation of equals or how the list uses it in your searches?

  • It would be correct if I stated: 1) the hashcode groups objects according to a precondition, such as the form of students that groups students by letter. 2) is used to compare objects within collections.

  • Math, one of my main doubts is how collections use the hashcode method to perform their searches.

  • Although I agree that the hashCode is not, strictly speaking, used to compare objects within collections, it gives the impression that the hashCode is not used when searching for objects within collections, which is not the case. One of the major bugs in the use of hashCode is the use of mutable fields, which can lead an object to be "lost" within a collection, since the hashCode is used as a kind of pre-filter.

  • @Danielc.Sobral fully agree, if the grupo is not found there is no way to find the object. Do you think my answer left this obscure?

  • 1

    I would not say that it is obscure: it is a natural conclusion of what you said, but my impression is that many people do not make this conclusion. I would prefer this kind of situation to be explicitly addressed.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.