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".
Related
EDIT: I'm new to java and am going through the official documentation in preparation for an upcoming subject in my Computer Science studies.
Original question:
So I checked this thread re: java == and .equals and am getting some unexpected results in dummy code that I'm writing.
I have this:
public class HelloWorld {
public static void main(String[] args){
Double double1 = 1.0; //object 1
Double double2 = 1.0; //object 2, which should be a different memory address?
System.out.println(double1.equals(double2)); //compare using the Object.equals() method
System.out.println(double1 == double2); //compare with ==
}
}
//Results are:
//true
//false
As expected, == produces a false because the two objects refer to different memory addresses.
However the double.equals(double2) is producing a true, which is not what I expected. In this example, I'm not overriding the default .equals() inherited from Object. My understanding is that equals checks for reference equality as well as values.
So why does double1.equals(double2) return true instead of false in this example? Are't double1 and double2 referring to two difference objects and therefore equals() should return false?
You didn't override equals, but the implementation of java.lang.Double does override it, to return true if the underlying values compare equal (plus a couple of edge cases).
https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#equals-java.lang.Object-
My understanding is that equals checks for reference equality as well as values.
That is incorrect.
The version of equals(Object) defined by java.lang.Object does that. But many classes override equals(Object) to have different semantics.
Double overrides it, and so do all of the other "primitive wrapper" classes, and String ... and many, many more.
The semantics of the override are typically equal-by-value, but not always. And some classes don't override equals. Examples where equals is not overridden that trip people up are StringBuilder and array types!
To find out the semantics for SomeType.equals(Object) you need to start with the javadocs for SomeType ... not Object.
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).
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".
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
I have a following Question
i have two empty Objects and i am using equals() method to compare them, as we know equals method compare contents of an Object, but in this case i dont have any properties to my Object
Object ob1 = new Object();
Object ob2 = new Object();
if(ob1.equals(ob2)){
System.out.println(" they are Equal");
}
else{
System.out.println("not equal");
}
if(ob1 == ob2){
System.out.println(" they are Equal");
}
else{
System.out.println("not equal");
}
we know == will compare the references of the Objects
what will equals method compare here ??
thanks in Advance ...
From the Object.equals 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).
It will also compare references, as stated here:
The equals method implements an equivalence relation on non-null object references:
It is reflexive: for any non-null reference value x, x.equals(x) should return true.
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
For any non-null reference value x, x.equals(null) should return false.
If both Objects are null then
if(ob1==null && ob2==null)
If you try to do ob1.equals(null) you will get NullPointerException. Since ob1 it self null.
== operator compare reference or memory location of objects in heap, whether they point to same location or not.
equals() method main purpose is two compare the state of two objects or contents of the object.
But you are using Object class equals() method.
Object class default implementation of equals() method work like == ,means it will check the memory reference of the object if they point to same location.
Note:
This default implementation is overridden to do content comparision in classes like String,Wrapper classes.
While there is some inconsistency about what X.equals(Y) should mean (i.e. what "question" should it answer), two useful questions are:
When the object is used as intended, should replacing some references to X with references to Y be expected not to change their behavior?
When the object is used as intended, would swapping all references to X with references to Y, and vice versa, be expected not to change their behavior?
If Object defined hashCode() to return the same value for all empty objects, and equals to return true when comparing any two empty objects to each other, those definitions would have satisfied #1. On the other hand, any object which defines equals to test reference equality and hashCode to return identityHashCode will also satisfy #1 (if X and Y are distinct instances, the fact that X.equals(X) is true but Y.equals(X) is false is, in and of itself, good reason to regard the objects as distinct.
While it's debatable whether Object should have been a concrete type, the only use of an instance of Object is as an identity token. As such, that fact that Object is a concrete type implies that its equals methods should test identity.