Behavior of the different forms of comparison in Java

15

If for example I have the code below, I'm comparing the object reference in the ex1 and ex2 case and not the object itself, correct?

Pessoa ex1 = new Pessoa();
Pessoa ex2 = new Pessoa();
if(ex1 == ex2)
{
    System.out.println("Igual");
}
else
{
    System.out.println("não é igual");
}

Here it is always printed that it is not the same, so I think I'm comparing correct references?

My other question is if this is the same as the above code that was typed:

Pessoa ex1 = new Pessoa();
Pessoa ex2 = new Pessoa();
if(ex1.equals(ex2))
{
    System.out.println("Igual");
}
else
{
    System.out.println("não é igual");
}
    
asked by anonymous 01.10.2014 / 19:27

4 answers

11

Response :

Comparison using: "==" versus "equals"

What is the Heap?

  

Heap is a reserved and protected JVM (Java Virtual Machine) where all objects instantiated during the execution of your program are allocated ... each of these objects has a memory address where it is stored, and the only one access to it, it is via a reference (stored outside the heap) .... This reference also has the memory address, making your access unique and exclusive to this object.

     
    

When you use the "==" operator to compare, you are comparing external to the heap already     the comparison using "equals" would be the inverse of the "==" operator that compares objects within the heap, that is, their characteristics.

  

In short:

  

"==" ---- > is used to compare two objects, verifying that objects refer to the same place in memory.
"equals" ---> this method is defined in the Object class, from which all classes are either a direct or indirect descendant. By default, the equals () method behaves the same as the operator == " but the String class overrides overrides the equals () method to compare the characters in a string and not their places in memory.

Note:

  

In addition, this is ideal when you create a new object, such as Person (as you created it), override the equals method inherited from Object, so we can see if people are really the same. An example would be if your Person class has both the age and name attributes you can override the equals / p>

public boolean equals(Pessoa p) {  

      boolean igual = false;  
      if ((this.nome.equals(p.getNome())) && (this.idade == p.getIdade()))  
         igual = true;  

      return igual;  
   }  

Search References:

  
    
      

Link Programmer Interview < br> Link Stack Overflow English
Link JavaFree

    
  
    
01.10.2014 / 19:46
8

As for the first doubt, you are correct.

Second:

Not necessarily. In Java the Equals method always looks for (or at least should, it depends on the actual implementation) to find the most descriptive comparison. It may even in some cases compare the reference, when this is the most descriptive way of comparing objects. But at first the benchmark comparison is avoided where possible.

The best example is the strings comparison. Identical strings but in different addresses return true when using Equals but false when using == (this is a bit more complicated than this because of interning , but this is another subject).

So for your specific case, it would even be the same thing. Unless the Equals implementation specifies the Pessoa class to change the default behavior.

By default Java, through class Object where all other classes are derived directly or indirectly, has an implementation of Equals that compares references.

But it would be appropriate for this class Pessoa to override the default implementation with another that is more descriptive. It takes some key field (s) and compares them to determine if it is the same identity or not. These fields would need to form a unique key, meaning no other instance of the class could be the same as another.

Is there an implementation? Only you can see it, we can not see it. You have to see in this class whether there is this implementation and how it is proceeding.

No Anthony Acciolly's review above has a link to his blog a> with a good example of implementation using the CPF as the unique identifier of the person's identity. This is a good way to make Equals of class Pessoa more relevant. Note that it is not at all extremely wrong to compare references in this case. But it is not the most intuitive. The ideal is to make this comparison have its own semantics. Here's how he did the Equals implementation for the class thinking about the object's various situations:

@Override
public boolean equals(Object obj) {
    // Um objeto é sempre igual a ele mesmo
    if (this == obj) {
        return true; 
    }
    // Um objeto nunca deve ser igual a null
    if (obj == null) {
        return false;
    }
    /* Uma pessoa só pode ser igual a outra pessoa.
     * Caso uma pessoa possa ser igual a uma de suas subclasses
     * use !(obj instanceof Pessoa)
     */
    if (getClass() != obj.getClass()) {
        return false;
    }
    // Converte a referencia para uma pessoa
    final Pessoa other = (Pessoa) obj;
    // Duas pessoas só podem ser comparadas se possuem CPF
    if (this.cpf == null || other.cpf == null) {
        return false;
    }        
    // Duas pessoas são iguais se possuem o mesmo CPF
    return this.cpf.equals(other.cpf);
}

I've placed it on GitHub for future reference.

See the implementation details on his blog (he kindly gave this example).

I'll talk about this in more detail in that answer . It is about C # and has some differences for Java, but there I explain this identity thing better. I also speak a little bit of identity here in this answer .

    
01.10.2014 / 19:36
6

By default, any class that declares no extension of another class, underneath the wads, will extend java.lang.Object . In your Person object, since you did not override the equals method that he inherited from java .lang.Object , the comparison will be made like this (source code of the equals method of java.lang.Object ):

public boolean equals(Object obj) {
    return (this == obj);
}

If you want to change the behavior of equals (which is perfectly normal to obey a contract of a possible entity for example), we would usually do (in a nutshell):

public boolean equals(Object obj) {
    return this.id == ((Pessoa) obj).id;
}

Here you would be saying that one person is just like another if ids are equal.

    
01.10.2014 / 19:44
0

"Here it is always printed that it is not the same, so I think I'm comparing correct references?"

Correct.

"My other question is if this is the same as the above code that was typed"

It's not the same. You can define the criterion that makes two people "equal" and implement this criterion in the public boolean equals(Object o) method of the same class which, with the aid of the @Override annotation, will overwrite the method inherited from the Object class. Example: two people are equal if their CPF are the same. There are some criteria that must be followed (contracts), mainly with the method compareTo of interface Comparable . I advise you to take a look at these contracts too, especially to follow community standards and make your code more robust.

    
10.11.2016 / 18:21