This question already has answers here:
What is the difference between == and equals() in Java?
(26 answers)
Closed 6 years ago.
As we know == compare references and equals() compare the content. But after checking equals() implementation in Object class I got confused. the implementation is,
public boolean equals(Object obj) {
return (this == obj);
}
as you see the implementation. equals internally calling == operator. Then how it different?
They're simply different in that you can override equals(), but cannot override == in any way.
So while equals() may check for logical equality of two objects if the class author decides so, == will always compare the reference and thus be true only if both operands are the same object (or same primitive value).
The equals() method compares the "value" inside String instances (on the heap) irrespective if the two object references refer to the same String instance or not. If any two object references of type String refer to the same String instance then great! If the two object references refer to two different String instances .. it doesn't make a difference. Its the "value" (that is: the contents of the character array) inside each String instance that is being compared.
On the other hand, the "==" operator compares the value of two object references to see whether they refer to the same String instance. If the value of both object references "refer to" the same String instance then the result of the boolean expression would be "true"..duh. If, on the other hand, the value of both object references "refer to" different String instances (even though both String instances have identical "values", that is, the contents of the character arrays of each String instance are the same) the result of the boolean expression would be "false".
Related
I was reading about the equals method in Java, and I heard people say that == tests for reference equality (whether they are the same object). .equals() tests for value equality (whether they are logically "equal").
I believe it is true but, If you look at the source code for .equals(), it simply defers to ==
From the Object class:
public boolean equals(Object obj) {
return (this == obj);
}
Now I am confused. What I see is we are testing if the current object have the same reference to the explicit parameter. Does it test for reference equality or for value equality?
From the Javadoc:
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
Object being the ultimate base class, this is the only definition of equals it can provide. There are no fields to compare across instances, so an instance can only be equal to itself.
In a comment you've said:
I would like to know about String comparison I see people use it all the time
Your question asks about Object, not String. String overrides equals, because Object's definition of equals isn't appropriate for String. Consequently, String defines its own (in keeping with the semantics required for equals implementations).
Object doesn't have a value to compare anything with.
But in order to make sense, it has to provide an implementation for methods such as equals() or hashCode().
So, to be precise: classes deriving from Object should override equals() in case they to replace reference equality with "value semantics".
public class Test {
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
System.out.print((o1 == o2) + " " + (o1.equals(o2)));
}
}
I read this in a different answer:
The == operator tests whether two variables have the same references (aka pointer to a memory address).
Whereas the equals() method tests whether two variables refer to objects that have the same state (values).
Here, since o1 and o2 reference two different objects, I get why == returns false.
But both the objects are created using the default constructor of the Object class, and therefore have same values. Why does the equals() method return false?
The implementation of equals() supplied by java.lang.Object is defined to return false, unless the references refer to the same object, in which case it returns true.
This is by design (the method mimics the behaviour of ==) and encourages programmers to implement their own version of equals(), if appropriate, for their class. For example, see java.lang.String#equals which compares the contents if another String is passed as an argument.
You have to write your own equals method that overrides the equals method of class Object because that method returns true if this object is the same as the object in the argument and false otherwise.
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). (for more information, read Javadoc)
All Java objects inherit from the Object class. The methods of Object, therefore, are available to all Java objects. One of these methods is equals().
The implementation for equals() in class Object, by default, is identical to the == operator.
If a programmer wishes to use equals() to test objects for value equality, he must override equals() and provide his own implementation (that should comply with the general contract for equals(); refer to the Javadoc).
public class SomeClass {
public static void main(String[] args){
int[] a={1,2,3};
int[] b={1,2,3};
int[] c=a;
String s="Neanderthal";
String s2="Neanderthal";
String s3=s;
System.out.println((a.equals(b))?"Same":"Different");
System.out.println((a.equals(c))?"Same":"Different");
System.out.println((s.equals(s2))?"Same":"Different");
System.out.println((s.equals(s3))?"Same":"Different");
}
}
The 1st system.out.print returns the value different and i cannot see a reason for this, and all the others are the same. Please help me understand this
Unlike Strings which are compared for equality character-by-character *, Java arrays are compared only for reference equality. You need to use Array.equals or Array.deepEquals to do the comparison:
System.out.println(Arrays.equals(a, b) ? "Same" : "Different");
* Since your code uses string literals, s and s2 would refer to the same object instance. However, this is not critical to understanding the issue at hand, because interning is not applicable to arrays.
When you say
int[] a={1,2,3};
int[] b={1,2,3};
a is pointing to an array, b is pointing to another array. Both the arrays are not same in the memory. That is, they both are pointing to different memory locations.Like :
a------------->|mem_loc_1|
b------------->|mem_loc_2|
Hence, equals() method tells you that both references are NOT pointing to same object.
Whereas when you say c= a;, the situation is :
a -------------> |mem_loc_1| <---------------- c
Hence equals() tells you that YES, a and c references reference to same objects.
Conclusion, when you say c = a; there are TWO references, but a single object in the memory.
P.S. Sorry for the bad graphical representation,just wanted to simplify things.
because it doesn't do deep equals and does just shallow equals, Use Arrays.deepEquals(); to get expected output
Before understanding above concept you need to note few things :
equals() method is defined in Object class, and any class can
override it.
By default equals() method use memory address of objects to compare them.
So, if you do not overriding it then it will call Object's method.
String class has overridden version of equals() method.
Now come on your program :
In first print statement you are comparing two different object which has not overridden equals() method, so it use Object's method and obviously it check memory address which is different.
In second print statement two reference variable refer same object so its address are same and equals() method return true.
In other print statements for string, which has overridden equals() method, so it will check only actual (here string value) content of object it doesn't matter two String reference variable referring same object or different.
I want a brief definition about the equals() , "==" and hashCode(). If i run following code means the output will be "true false 2420395 2420395". But i had understand that equals() method compares the string and "==" compares the reference. But in output the hashCcode() method prints the reference number for both strings as same then why the "==" returns "false".
String str = "Name";
String str1 = new String("Name");
if (str.equals(str1))
System.out.println("true");
else
System.out.println("false");
if (str == str1)
System.out.println("true");
else
System.out.println("false");
System.out.println(str.hashCode());
System.out.println(str1.hashCode());
The equals() and hashCode() methods prove to be very important, when objects implementing these two methods are added to collections. If implemented incorrectly it might screwed up your life.
equals() : This method checks if some other object passed to it as an argument is equal the object in which this method is invoked. It is easy to implement the equals() method incorrectly, if you do not understand the contract. Before overriding this method, following “properties” need to keep in mind -
Reflexive: o1.equals(o1) - which means an Object (e.g. o1) should be equal to itself
Symmetric: o1.equals(o2) if and only o2.equals(o1)
Transitive: o1.equals(o2) && o2.equals(o3) implies that o1.equals(o3) as well
Consistent: o1.equals(o2) returns the same as long as o1 and o2 are unmodified
null comparison : !o1.equals(null) - which means that any instantiable object is not equal to null. So if you pass a null as an argument to your object o1, then it should return false.
Hash code value: o1.equals(o2) implies o1.hashCode() == o2.hashCode() . This is very important. If you define a equals() method then you must define a hashCode() method as well. Also it means that if you have two objects that are equal then they must have the same hashCode, however the reverse is not true
From java source code
*
* #param obj the reference object with which to compare.
* #return {#code true} if this object is the same as the obj
* argument; {#code false} otherwise.
* #see #hashCode()
* #see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
hashCode(): This method returns a hashCode() value as an Integer and is supported for the benefit of hashing based java.util.Collection classes like Hashtable, HashMap, HashSet etc. If a class overrides the equals() method, it must implement the hashCode() method as well.Before overriding this method, you need to keep in mind
Whenever hashCode() method is invoked on the same object more than once during an execution of a Java program, this method must consistently return the same result. The integer result need not remain consistent from one execution of the program to the next execution of the same program.
If two objects are equal as per the equals() method, then calling the hashCode() method in each of the two objects must return the same integer result. So, If a field is not used in equals(), then it must not be used in hashCode() method.
If two objects are unequal as per the equals() method, each of the two objects can return either two different integer results or same integer results (i.e. if 2 objects have the same hashCode() result does not mean that they are equal, but if two objects are equal then they must return the same hashCode() result).
As per java source code
As much as is reasonably practical, the hashCode method defined by java.lang.Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer)
hashCode() does not return the object's reference, but a hash of the object, computed in some way. == does not compare objects using the value of hashCode() but, as you correctly say, by the value of the objects' references.
.equals() compares the actual content of the string.
The "==" operator compares if the two objects are the same reference in memory. If you were to do str = str1;, then the double-equals operator would return true because they point to the same reference in memory.
hashCode() returns a hash of the object in an arbitrary manner. The value returned will always be unique as long as the method is not overridden in some way. If .equals() returns true, the hash code should be the same.
You can read the hashCode documentation. In a few words it says that if (obj1.equals(obj2) is true then obj1.hashCode()==obj2.hasCode() must be true to be a valid implementation.
Note that it does not mean that two different objects cannot share the same hash code. Actually, this example is a valid (but awful) implementation of the method:
class MyClass {
public int hashCode() {return 0;}
}
equals() and hashCode() are different methods and hashCode method should not be used to check if two object references are same.
Reason: hashCode just returns int value for an Object, even two different objects can have same hashCode integer. The value returned by hashCode() is the object's hash code, which is the object's memory address in hexadecimal.
equals() checks if the two object references are same. If two objects are equal then their hashCode must be the same, but the reverse is not true.
As other said '==' compares references. But the two methods are just methods doing something which can be overridden.
Every method does something. If you want to know what it exactly does and what is its meaning you need to read the documentation.
You may override those methods in anyway you want. But please note that you must follow JAVA documentation for these two methods. Because they are used by other classes. For example equals() is used while you try find an object in a list and .hashCode() is used in some hashtable classes provided by JAVA class library.
equals() only compare string it's does not check reference of string
but '==' check reference and data both
in 1st case String str = "Name"; only one object is created but in
2nd case Two object is created
String str1 = new String("Name");
then reference are not same of both string that means it returns false
Is it possible to compare 2 object from 2 different classes.
lets say i have an vector which adds all the objects from class A. i want to compare some string to the elements of the vector.
Example:
if(string.equals(vector.get(i)))
is this possible ?
Yes, you can call equals(). However, any reasonable implementation of SomeClass.equals() would return false if the argument is of a different class (other than perhaps a subclass).
If string is an instance of java.lang.String, this behaviour is specifically guaranteed:
The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
Your objects are at least in the class Object, and thus (at least partly) in the same class.
Equals method of an object can take any other object. However, it would be up to the implementation to not return true when comparing an apple with an orange
If the list's elements have type other than String it will always return false. From the String documentation for method equals:
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
This is generally true for the method equals - it will or should return true only in the eventuality that the compared object is of the same class or a subclass of the former.
It's perfectly valid to write something like;
public class MyClass {
public boolean equals(Object o) {
if(o instanceof SomeUnrelatedClass) return true;
return false;
}
}
But it is not advisable, as least I would try to avoid it. It would make handling MyClass objects a little strange, for example putting them into a hash-based collection.