why equals() method when we have == operator? [dup

2019-01-01 16:41发布

问题:

This question already has an answer here:

  • How do I compare strings in Java? 23 answers

When i see the implementation of equals() method it does nothing but same as what == does. So my question is what was the need to have this as separate method when we have == operator which does the same work?

回答1:

You can not overload the == operator, but you can override equals(Object) if you want it to behave differently from the == operator, i.e. not compare references but actually compare the objects (e.g. using all or some of their fields).

Also, if you do override equals(Object), have a look at hashCode() as well. These two methods need to be compatible (i.e. two objects which are equal according to equals(Object) need to have the same hashCode()), otherwise all kinds of strange errors will occur (e.g. when adding the objects to a set or map).



回答2:

== compares object references, and asks whether the two references are the same.

equals() compares object contents, and asks whether the objects represent the same concept.



回答3:

In case of primitives, the == operator checks if two values are the same.
If it aren\'t primitives, it checks if it are two pointers (or references) pointing to the same instance of an object.

The equals() method performs a custom check, which is in Object checking the reference, by using ==. But in other classes, sometimes equals() is overridden (I don\'t know if this is a correct past participle). equals() have to check the content.

So, for example:

int i0 = 34;
int i1 = 34;
int i2 = 35;
// results
i0 == i1: true
i1 == i0: true
i2 == i0: false

But if we have non-primitives

String str0 = new String(\"Hello man!\");
String str1 = new String(\"Hello man!\");
String str2 = new String(\"!nam olleH\");
String str2copy = str2;
// Results
str0 == str1: false // Pointer to two different object, so == will give false
str1 == str2: false // Idem
str2 == str2copy: true // So this are two pointers to the same object
str0.equals(str1): true // This are not the same objects, but they are equal
str1 == str1: true // Again: two times a pointer to the same  object

So, why str0.equals(str1) returns true? Because the String class has an override of equals(). And in that method it doesn\'t check if they are equal by doing return this == obj; But in that method, there is a full check. I don\'t know which method they use to compare the two strings, but here are two possible ways:

  • Generating from the the two string a hash-code and check if they are equal (int == int)
  • Checking character by character if they are the same.

So I hope this is clear now.



回答4:

There is a very important difference between the two.

\"==\" compares object instances. The default equals() implementation does this, also. Please run & analyse the following code sample:

public class Person{
   String name;

   public Person(String name){
       this.name = name;
   }

//overriding equals
public boolean equals( Object obj ) {
    if( this == obj )
        return true;
    if( obj == null )
        return false;
    if( getClass() != obj.getClass() )
        return false;
    Person other = (Person) obj;
    if( name == null ) {
            if( other.name != null )
            return false;
    } else if( !name.equals( other.name ) )
        return false;
    return true;
    }
     }

    ...
    ...
    Person john1 = new Person(\"John\");
    Person john2 = new Person(\"John\");
    System.out.println(\"john1 == john2:\" + (john1 == john2));
    System.out.println(\"john1.equals(john2):\" + john1.equals(john2));

As you can see, \"==\" will return false (the objects are two different instances of Person), whereas equals will return true (because we defined that 2 Persons are equal when they have the same name)



回答5:

== operator is used to compare references.
equals() method is defined over object definition.

Dog d =new Dog();
Collar c =new Collar(\"Red\");
 d.setCollar(c);
Dog d2=new Dog();
 Collar c2=new Collar(\"Red\");
d2.setCollar(c2);

 d2.getCollar() ==d.getCollar()

would return false indicating that the the two dogs have two different collar object (items).they do not share the same collar.

d2.getCollar().equals(d.getCollar())

return true if the Collar is defined as [Collar are same if color of Collar are same] the two dogs have same colored collar.

   class Collar{
    String color=\"\";
    public Collar(String p0){
    this.color=p0;
    }
    boolean equals(Object c){
      Collar other=(Collar)c;
      return  this.color.equals(other.getColor());
    }

    public String getColor(){
      return this.color;
    }
    }


回答6:

That\'s done so to make this possible:

String s1 = new String(\"foo\");
String s2 = new String(\"foo\");

System.out.println(s1 == s2); // false?! Different references!
System.out.println(s1.equals(s2)); // true

If you check the source of String#equals(), you\'ll see that it has overridden the Object#equals() appropriately to compare each other\'s internal character array (the actual value). Many other classes have this method overridden as well.



回答7:

\"string\" == \"string\" will return false \"string\".equals(\"string\") will return true

With o1 == o2 you compare that the object 1 is the same object than o2 (by reference)

With o1.equals(o2), depending on the object the equals method is overriden and not implemented with something like \"return o1 == o2\"

For exemple you create 2 Set instances These 2 set objects are 2 different objects, you can add different elements in any of those. set1 == set2 will always return false but set1.equals(set2) will eventually return true if the set2 contains exactly the same elements that set1... and because equals method is overriden in the Set class...

Equals implementation for Set is:

      public boolean equals(Object o) {
        if (o == this)
           return true;

        if (!(o instanceof Set))
             return false;
        Set s = (Set) o;
        if (s.size() != c.size())
             return false;
        return containsAll(s); // Invokes safe containsAll() above
    }


回答8:

In java equals operator(==) operates on data of two variables if the operands are of primitive data types. But if the operands are objects java compares them using references because it has no way to figure out to compare on which field or fields of the object.

So there is only one way to compare based on user defined fields and that is defined in the object by overriding equals() methods, since equals operator(==) cannot be overrided in java as java does not supports operator overriding.

As an example if you want to compare Employee on the basis of name you need to define it\'s logic by overriding equals method in Employee class as below:

public class Employee {
    private Integer id;
    private String name;

    @Override
    public boolean equals(Object obj) {
        Employee other = (Employee) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }


}