I just started learning Java and came across equals. After looking for the difference between equals and ==, I decided to practice it myself but I am not getting the expected results. here is the code:
public class Sandbox {
/**
* #param args
*
*/
private int a;
public void setAtta(int value){a=value;}
public int getAtta(){return a;}
public static void main(String[] args) {
// TODO Auto-generated method stub
Sandbox s = new Sandbox();
s.setAtta(10);
Sandbox s1 = new Sandbox();
s1.setAtta(10);
System.out.println(s==s1);//false- EXPECTED
System.out.println(s.equals(s1));//false- I thought it should be true?
}
}
Object.equals in Java is equivalent to ==, i.e. it tests reference equality. Since your Sandbox class (implicitly) extends Object, and you don't override equals, s.equals(s1) calls Object.equals.
To get the behaviour you want, add an equals method (override) to your class:
public boolean equals(Object obj) {
if(this == obj) return true;
if(!(obj instanceof Sandbox)) return false;
Sandbox that = (Sandbox)obj;
return this.a == that.a;
}
equals() method in object class, just use == comparison behind the screen. So you got it as false. So you need to override it and give your implementation as needed.
public boolean equals(Object o){
if(o instanceof SandBox){
if(((SandBox)o).a==this.a){
return true;
}
}
return false;
}
This is how it works:
equals is an Object class method that you can override.
In String class, it is already overridden.
If you want your code, to work, you have to define your own equals method code. Because, obviously, Object class's code is not valid for sandbox class.
The method signature for equals is:
public boolean equals(Object obj);
the difference between == and equals is that == checks equality in references and equals checks equality in value. tell me please, what is the value of an object? that is why the result is false. unless overridden the equals of sandbox will invoke the equals of the Object class. You should override the equals function to check equality between you custom objects.
Related
I constructed a class with one String field. Then I created two objects and I have to compare them using == operator and .equals() too. Here's what I've done:
public class MyClass {
String a;
public MyClass(String ab) {
a = ab;
}
public boolean equals(Object object2) {
if(a == object2) {
return true;
}
else return false;
}
public boolean equals2(Object object2) {
if(a.equals(object2)) {
return true;
}
else return false;
}
public static void main(String[] args) {
MyClass object1 = new MyClass("test");
MyClass object2 = new MyClass("test");
object1.equals(object2);
System.out.println(object1.equals(object2));
object1.equals2(object2);
System.out.println(object1.equals2(object2));
}
}
After compile it shows two times false as a result. Why is it false if the two objects have the same fields - "test"?
== compares object references, it checks to see if the two operands point to the same object (not equivalent objects, the same object).
If you want to compare strings (to see if they contain the same characters), you need to compare the strings using equals.
In your case, if two instances of MyClass really are considered equal if the strings match, then:
public boolean equals(Object object2) {
return object2 instanceof MyClass && a.equals(((MyClass)object2).a);
}
...but usually if you are defining a class, there's more to equivalency than the equivalency of a single field (a in this case).
Side note: If you override equals, you almost always need to override hashCode. As it says in the equals JavaDoc:
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
You should override equals
public boolean equals (Object obj) {
if (this==obj) return true;
if (this == null) return false;
if (this.getClass() != obj.getClass()) return false;
// Class name is Employ & have lastname
Employe emp = (Employee) obj ;
return this.lastname.equals(emp.getlastname());
}
The best way to compare 2 objects is by converting them into json strings and compare the strings, its the easiest solution when dealing with complicated nested objects, fields and/or objects that contain arrays.
sample:
import com.google.gson.Gson;
Object a = // ...;
Object b = //...;
String objectString1 = new Gson().toJson(a);
String objectString2 = new Gson().toJson(b);
if(objectString1.equals(objectString2)){
//do this
}
The overwrite function equals() is wrong.
The object "a" is an instance of the String class and "object2" is an instance of the MyClass class. They are different classes, so the answer is "false".
It looks like equals2 is just calling equals, so it will give the same results.
Your equals2() method always will return the same as equals() !!
Your code with my comments:
public boolean equals2(Object object2) { // equals2 method
if(a.equals(object2)) { // if equals() method returns true
return true; // return true
}
else return false; // if equals() method returns false, also return false
}
The "==" operator returns true only if the two references pointing to the same object in memory. The equals() method on the other hand returns true based on the contents of the object.
Example:
String personalLoan = new String("cheap personal loans");
String homeLoan = new String("cheap personal loans");
//since two strings are different object result should be false
boolean result = personalLoan == homeLoan;
System.out.println("Comparing two strings with == operator: " + result);
//since strings contains same content , equals() should return true
result = personalLoan.equals(homeLoan);
System.out.println("Comparing two Strings with same content using equals method: " + result);
homeLoan = personalLoan;
//since both homeLoan and personalLoan reference variable are pointing to same object
//"==" should return true
result = (personalLoan == homeLoan);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);
Output:
Comparing two strings with == operator: false
Comparing two Strings with same content using equals method: true
Comparing two references pointing to same String with == operator: true
You can also get more details from the link: http://javarevisited.blogspot.in/2012/12/difference-between-equals-method-and-equality-operator-java.html?m=1
Statements a == object2 and a.equals(object2) both will always return false because a is a string while object2 is an instance of MyClass
Your implementation must like:
public boolean equals2(Object object2) {
if(a.equals(object2.a)) {
return true;
}
else return false;
}
With this implementation your both methods would work.
If you dont need to customize the default toString() function, another way is to override toString() method, which returns all attributes to be compared. then compare toString() output of two objects. I generated toString() method using IntelliJ IDEA IDE, which includes class name in the string.
public class Greeting {
private String greeting;
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
return this.toString().equals(obj.toString());
}
#Override
public String toString() {
return "Greeting{" +
"greeting='" + greeting + '\'' +
'}';
}
}
Your class might implement the Comparable interface to achieve the same functionality. Your class should implement the compareTo() method declared in the interface.
public class MyClass implements Comparable<MyClass>{
String a;
public MyClass(String ab){
a = ab;
}
// returns an int not a boolean
public int compareTo(MyClass someMyClass){
/* The String class implements a compareTo method, returning a 0
if the two strings are identical, instead of a boolean.
Since 'a' is a string, it has the compareTo method which we call
in MyClass's compareTo method.
*/
return this.a.compareTo(someMyClass.a);
}
public static void main(String[] args){
MyClass object1 = new MyClass("test");
MyClass object2 = new MyClass("test");
if(object1.compareTo(object2) == 0){
System.out.println("true");
}
else{
System.out.println("false");
}
}
}
the return type of object.equals is already boolean.
there's no need to wrap it in a method with branches. so if you want to compare 2 objects simply compare them:
boolean b = objectA.equals(objectB);
b is already either true or false.
When we use == , the Reference of object is compared not the actual objects. We need to override equals method to compare Java Objects.
Some additional information C++ has operator over loading & Java does not provide operator over loading.
Also other possibilities in java are implement Compare Interface .which defines a compareTo method.
Comparator interface is also used compare two objects
Here the output will be false , false beacuse in first sopln statement you are trying to compare a string type varible of Myclass type to the other MyClass type and it will allow because of both are Object type and you have used "==" oprerator which will check the reference variable value holding the actual memory not the actual contnets inside the memory .
In the second sopln also it is the same as you are again calling a.equals(object2) where a is a varible inside object1 . Do let me know your findings on this .
In short, == compares two POINTERS.
If the two pointers are equal, then they both point to same object in memory (which, obviously has the same value as itself).
However, .equals will compare the VALUES of whatever is pointed to, returning true iff they both evaluate to the same value.
Thus, two separate strings (i.e., at different addresses in memory) are always != but are .equal iff they contain the same (null-terminated) sequence of chars.
IN the below code you are calling the overriden method .equals().
public boolean equals2(Object object2) {
if(a.equals(object2)) { // here you are calling the overriden method, that is why you getting false 2 times.
return true;
}
else return false;
}
I have been reading a book called Thinking in Java on Java(I come from C background). I came across the following two set of codes
public class EqualsMethod {
public static void main(String[] args) {
Integer n1 = new Integer(47);
Integer n2 = new Integer(47);
System.out.println(n1.equals(n2));
}
}
//Output: true
I understand that this equal method is comparing the reference. But n1 and n2 are two object residing in ´two different "bubble" in the heap. So how come they are equal?
Another example code is
class Value {
int i;
}
public class EqualsMethod2 {
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));
}
} /* Output:false
}
Why does this give false? Your in depth answer would be much anticipated. Thank you.
The behavior of equals in your custom classes is entirely up to you. If you override it, you decide when two objects of your class are considered equal to each other. If you don't override it, you get the default implementation of Object class, which checks if both references refer to the same object (i.e. checks if v1==v2 in your example, which is false).
Root of the issue :
You have not overrriden eqauals and hashCode and then JVM assigns a new hashCode to any object you create in the case of Value class
=================
Solution :
You will need to define the criteria on which the identities of the value object is measured i.e do the following
1) Override the equals method and specify that the equality is checked over the value of the instance variable i
2) Override Hashcode and use instance variable i for the hashCode comparison
== is used in the equals method in the object class to avoid unnecessary calculation if the two refrences point to the same object and if not go ahead with the calculation and comparisons
public boolean equals(Object anObject)
{
if (this == anObject) {
return true;
}
else{
// Do the calculation here to check the identity check
}
I understand that this equal method is comparing the reference.
Wrong. In the Object class, this method contains a referential comparison, but Integer has it's own implementation, which overrides the one provided by Object.
It compares the values of the two Integers, not their references.
Integer is valuable type. So comparing to Integer variables performing by comparing their values. Which are equal in your particular case.
Comparing two objects (reference type) performing by comparing the references, which are not equal.
You could write your own comparison logic by overloading the equals() method in your class.
Integer has the method equals() that compare the value, and your Value class doesn't. It makes the Value class with equals compare the "pointer", and they're different.
If you override the method equals in your class Value comparing the attribute i from the class, it would return true.
For example
public boolean equals(Object o){
return (this.i == ((Value) o).i) ? true : false;
}
Equals method in all Wrapper classes is overridden by default in java. That's is why first snippet works.
For your own classes, you have to provide an implementation of equals method.
By default the equal method in Java check if the two Object references are the same. You can #Override the method, and do what you want. So it is normal that you get False, because the two Object are different.
So how come they are equal?
Integer is an Object. On the other side int is a simple type.
Integer's equals() method compare int inside, because it's overriding Object equals() method. int's there has the same value.
Why does this give false?
Your Value class doesn't override equal's method, so then refferences are compared, exactly like when you write v1 == v2. In this case they are different Objects so it's false.
Because you have not override equals method. If you do not override it then it will check if the reference are equal or not and return accordingly.
You can refer equals() method defined in Integer class.
System.out.println(n1.equals(n2)) // this prints true because it refers to Integer equals method.
Similarly you will have to override it for your Value class like.
class Value {
int i;
#Override
public boolean equals(Object obj) {
boolean returnValue = false;
if (obj != null && obj instanceof Value) {
Value valObj = (Value) obj;
if (this.i == valObj.i) {
returnValue = true;
}
}
return returnValue;
}
}
Now System.out.println(v1.equals(v2)); prints true.
Hi your understanding of equals and == is completely wrong or opposite to what it actually is.
equals() method also checks for reference as == does, there is no difference between both of them unless you override the equals method.
== check for reference equality. For better understanding see Object class source code.
public boolean equals(Object obj) {
return (this == obj);
}
Why is it working in your case? is because Integer class overrides the equals method in it.
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
n
}
Now when you use your custom class to check equality what it is doing is basically calling.
v1==v2
How it can give you true? They both have different memory locations in heap.
If still things are not clear put break points in your code and run it in debug mode.
This question already has answers here:
Overriding the java equals() method - not working?
(8 answers)
Closed 9 years ago.
I've got a Node<T> with an equals() method:
public boolean equals(Node<T> other) {
if (this == other)
return true;
if (other == null)
return false;
if (!obj.getClass().equals(other.getObject().getClass()))
return false;
return obj.equals(other.getObject());
}
I only care if the object held in my node is equal to the object held in the other node (because two equal objects can be held in different positions in my list).
The object I'm holding is a Token. The Token.equals() method works while my Node.equals() method does not:
public class TokenEqualityTest {
public static void main(String[] args) {
Token t = new Token(0);
Token q = new Token(0);
System.out.println("t.equals(q): " + t.equals(q));
Node<Token> tnode = new Node<Token>(null, null, t);
Node<Token> qnode = new Node<Token>(null, null, q);
System.out.println("tnode.equals(qnode): " + tnode.equals(qnode));
}
}
which prints:
t.equals(q): true
tnode.equals(qnode): false
If I put a breakpoint at Token.equals() and run the eclipse debugger, my code stops once (at t.equals(q)). This indicates that Node<Token>.equals() does not call Token.equals, and I have verified that the debugger does step through the line return obj.equals(other.getObject());.
Why doesn't my Node.equals ever call Token.equals when I've declared a Node<Token>?
Your equals method should have the following signature:
public boolean equals(Object obj)
And when you override equals method, you should override hashCode method, too. This is contract that all object should follow.
For prevent this kind of mistake, it would be better to add #Override annotation.
Or you can use lombok to simplify defining equals and hashCode methods by #EqualsAndHashCode annotation.
My psychic debugging skills tell me that you didn't override the base equals() method in Token, just like you didn't in Node.
You need to declare it as equals(Object).
Add the #Override annotation to catch that.
The equals method must take an Object type as a parameter in order to override the parent class equals method. It should also return a primitive boolean type.
You need to override equals method this way:
#Override
public boolean equals(Object object) {
// add your logic here
}
Also you need to override hashCode method. This is the contract:
#Override
public int hashCode() {
return hashCode;
}
Here is my code:
import java.util.HashMap;
class MyString
{
String string;
MyString(String string)
{
this.string = new String(string);
}
}
public class test
{
public void test3()
{
HashMap<MyString, Byte> byteHashMap = new HashMap<MyString, Byte>();
char c = 'A';
byte b = (byte)c;
String string = new String("The Letter A");
MyString myString = new MyString(string);
byteHashMap.put(myString, b);
if (byteHashMap.containsKey(myString))
//if (byteHashMap.containsKey(new MyString(string)))
{
System.out.println("true");
}
else
{
System.out.println("false");
}
}
public static void main(String[] args)
{
test testObject = new test();
testObject.test3();
}
}
I would like to know why the code, as is, returns true. However, when I switch the if statements (see the commented line), it returns false.
I believe it has something to do with overriding the equals method in the MyString class but I am unsure how to approach this.
Regards.
Your belief is correct. Map structures rely on .equals to determine if a key already exists in the map or not. By default, object types have instance equality (meaning a.equals(b) is true if and only if a and b point to the same object).
In your case, you probably want two MyString instances to be equal if the string field is equal. In this case, you would override equals with something like:
#Override
public boolean equals(Object other) {
if (other == null) { return false; }
if (!(other instanceof MyString)) { return false; }
MyString m = (MyString)other;
return this.string.equals(m.string);
}
With this, either of the two if statements would return true.
You should also override hashCode. If you use Eclipse, it can generate these two methods for you quite easily via the Source menu.
Yes, override hashCode and equals.
Right now you will compare a string against the memory reference (standard implementation) of your MyString object.
example
#Override
public bool equals(Object args0) {
if(args0 == this) { return true; }
if(!(args0 instanceof MyString)) { return false; }
MyString obj = (MyString) args0;
return obj.getString().equals(this.string); // Create getter
}
#Override
public int hashCode(){
return this.string.hashCode() * 37;
}
You need to implement hashCode and equals. HashMaps put objects in buckets based on the hashCode. Different objects can have the same hashCode, but the rule is that two equal objects must have the same hashCode. Once the HashMap finds all of the entries with the same hashCode, it then checks for equality using the equals method.
The default implementation checks for object instance equality - that is, are the two objects the same instance. In your case, you're checking two different instances.
Override the equals and hashCode methods to pass through the values returned by hashCode() and equals() for the private String member variable, assuming that's all that determines if two instances of your class are equal.
This question already has answers here:
Why do I need to override the equals and hashCode methods in Java?
(31 answers)
Closed 9 years ago.
public class Account {
String account;
double balance;
Account(String account, double balance) {
this.account = account;
this.balance = balance;
}
}
public class AccountTest {
public static void main(String[] args) {
Account a1 = new Account("Sandy", 1000);
Account a2 = new Account("Sandy", 1000);
System.out.println(a1.equals(a2));
}
}
When i execute it showing "false" but objects contains same data in variables.why?explain.
Because by default object checks equality based on equals(Object obj).
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).
If you want to check equality with equals() method in your class equal you have to override equals() method of Object class.
how-to-override-equals-method-in-java, Like following:
#Override
public boolean equals(Object obj) {
// your implementation
}
And you should always override hashCode() whenever overriding equals method of Object class.
#Effective Java, by Joshua Bloch
You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.
You need to override equals() method, and use it whenever you want to compare their values.
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Account other = (Account) obj;
if ((this.account== null) ? (other.account!= null) : !this.account.equals(other.account)) {
return false;
}
if (this.balance!= other.balance) {
return false;
}
return true;
}
BUT WHY I HAVE TO OVVERIDE EQUALS()
You need to overrides equals
#Override
public boolean equals(Object obj) {
if (!(obj instanceof Account))
return false;
Account that = (Account) obj;
return (account == null ? that.account == null : account
.equals(that.account)) && balance == that.balance;
}
I almost forgot to override hashCode when overriding equals
#Override
public int hashCode() {
int hash = 17;
hash = 37 * hash + (account == null ? 0 : account.hashCode());
long l = Double.doubleToLongBits(balance);
hash = 37 * hash + (int) (l ^ (l >>> 32));
return hash;
}
You did not override equals. The default equals implementation, inherited from Object, returns true if and only if the two variables point to the same object.
Override equals to check for field equality (and hashCode, if you're at it).
The Object.equals() method is testing to see if the two things being compared are LITERALLY the same object. While a1 and a2 contain the same information, they are different objects in memory.
If you want to test equality of the information inside your objects you can have the class implement the Comparable interface and override the compareTo method.
Since you don't override .equals() (and if you do, you must also override .hashCode()), you use Object's .equals() implementation; and this implementation returns true if and only if the object references are equal (ie, o1 == o2).
You need to override Object.equals() method.
It would show true if a1.balance==a2.balance . Note that the equals() compares objects and not their actual values. To be able to compare an Object you have to overwrite the equals() method.
See here for more info Comparing two objects using an equals method, Java
The implementation in Object class i.e. the default implementation checks the references.
So if the references are same it returns true else it returns false.