Object Comparison

Asked

Viewed 5,688 times

8

The code below generates a false, but objects have the same attribute values, there is some method that compares objects, but their attributes, and not the object itself?

Produto P5 = new Produto(1, 0, 10,1000.0,"Samsung","smartphone");
Produto P6 = new Produto(1, 0, 10,1000.0,"Samsung","smartphone");  
System.out.println(P5.equals(P6));
  • Don’t forget that modern Ides (Eclipse, Intellij Idea) can automatically generate the equals and hashcode for you.

2 answers

4


The result of comparing objects is done through the methods hashCode() and equals(), class Object. Therefore, to make the comparison your way you must write these methods in your class Produto.

Creating a Product class to my liking (since you didn’t say the attributes names), would look something like this:

Product

public class Produto {

    int idProduto;
    String nomeProduto;

    //getters and setters

    @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());
    }   

}

The method hashCode is used to expedite the search in Collections, and must always return the same value to the same object, in the above case I preferred to return the idProduto for if the idProduto it is different neither to go to the equals(), for surely he will return false.

  • Wouldn’t it be better to have the same fields in equals and hashcode? One is the complement of the other, and although the equals are the ones who give the last word about the object being the same or not, the ideal would be that the hashcode method also took the product name into account - or that the equals did not use the product name.

  • @Raviwallau I see no reason to do this, as you msm said the equals gives the last word on the result of the comparison, even in this case in specific if it does not overwrite the hashcode still work, but I preferred to keep the contract what it says to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes. The hashCode, as said in the reply, it does not have the function to compare, it only serves to expedite the searches in Collections.

  • Well... as a rule I always maintain the same fields in both methods, more because I see no reason not to. A good hashcode is a hashcode that minimizes the chance of collisions, and in your case, the chances of collision increase.

  • @Raviwallau understand your point, but I believe that there is a rule that is the best in all cases. In the above case I am using the idProduto to define the hashCode, I believe the id is unique, if it is not, there really will be a way to implement a hashCode better than I implemented. But for didactic means my example meets, since I fulfilled the contract of equals, of hashCode and I have overwritten the method that generates the hashCode in a way that it is not as inefficient as possible, which would be the case to return a.

  • @Raviwallau You can go deeper on the subject como gerar um hashcode utilizando todos os atributos da classe posting your own answer if you think it’s relevant to the question. Maybe it’s a good one, because I don’t usually do it myself with my codes real-life, and future visitors could enjoy such information.

2

You are not forgetting to specialize in the equals for Produto?

Must be something like:

@Override
public boolean equals(Object other)
{
    if (other == null) 
        return false;

    if (other == this)
        return true;

    if (!(other instanceof Produto))
        return false;

    Produto p = (Produto) other;

    // Aqui você implementa como deve se feita a comparação.
    // Verifica se os nomes dos produtos são iguais, ids e etc.

    if (p.id == this.id) {
        return true;
    } else {
        return false;
    }
}

Browser other questions tagged

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