equals() and operator "==" in java - java

I know that equals() will compare the value of objects, the '==' operator will check if the variable point to the same memory.
I do not understand how equals() compare the value of objects, for example:
class Test {
public Test(int x, float y) {
this.x = x;
this.y = y;
}
int x,
float y;
}
Test test1 = new Test(1,2.0);
Test test2 = new Test(1,2.0);
So if I use equals(), will it compare each properties in each object?
And what about if we are talking about String? using equals() and operator “==”, do we still need to override the equals()?

No, if you don't override the equals-method in your class, then equals is the same as ==. See the documentation for this:
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).
The documentation also states what requirements there are for equals methods in case you want to implement it.

Not unless you overload it properly according to the rules laid down by Joshua Bloch.
The default behavior checks equality of references using ==.
It's important to override equals and hashCode for your objects, especially if you intend to use them in java.util.Collections.

The equals method is defined in class Object, and since all objects in Java implicitly or explicitly inherit from this class, they too will inherit the equals() method as implemented by Object. The default implementation in Object will simply return true if the objects pass the "==" condition.
However, you are free to override the equals() method in your own class and specify the criteria which must be checked to see if two objects are meaningfully equal. For example, you might say that two instances are only equal if each of its attributes contain the same values as another object, or you might instead want to simply check a few attributes which make up the objects "business key" and ignore the others.
The equality of String classes follow the same rules as any other class in Java; "==" will be true if they do refer to the same instance, and equals() will be true if they contain the same values.

Related

equals method usage in string and list

on the oracle java documentation,
equals() from list says two lists are defined to be equal if they contain the same elements.
But from object class equals() return true only if their hash code is equal.
It means equals() from list overrides equals method from object class. And it's same for equals() from string. As long as they have same characters, they return true.
so whenever I declare a type as String, or use list classes like arraylist
equals() are overriden automatically righT?
equals() are overridden automatically righT?
Answer : Yes absolutely right, If you are asking overriden .equals() method is invoked automatically at run time
**Object class is parent class for every class in java and it consist of .equals() method which compares the object references
But String class, Wrapper classes (Integer,Long etc..) and Collections Classes (ArrayList, hashSet etc..) are overridden .equals() method to compare content in object instead of object references
to avoid confusions here is the clear example
public class Main2 {
public static void main(String[] args) {
List<String> l1 = new ArrayList<>();
l1.add(new String("hello"));
List<String> l2 = new ArrayList<>();
l2.add(new String("hello"));
System.out.println(l1.equals(l2)); //true
List<Test> t1 = new ArrayList<>();
t1.add(new Test());
List<Test> t2 = new ArrayList<>();
t2.add(new Test());
System.out.println(t1.equals(t2)); //false
}
}
class Test{
}
In the above example comparing List<String> will return true because .euqals() method in String is overridden to compare content
But while comparing Lits<Test> will return false even though both objects are empty, since .equals() method in Test class is not overridden by default it will invoke Object class .equals() method which compares reference of objects as == does
Google Question object class equals method compares hashcode ?
Answer
The java.lang.Object class requires that any two objects that compare equal using the equals() method must produce the same integer result when the hashCode() method is invoked on the objects [API 2014]. The equals() method is used to determine logical equivalence between object instances.Feb 12, 2018
equals() are overriden automatically righT?
No. Methods are not overwritten "automatically".
You can look at the code - both classes have their own implementation of equals and hashCode. This implementation is what is used at runtime. If you're writing your own class, you will likely implement equals and hashCode.
But from object class equals() return true only if their hash code is equal.
I think you (and the original version of the other answer) are misunderstanding the documentation on equals:
Indicates whether some other object is "equal to" this one.
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.
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).
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.
The only part of this that refers to hashCode is at the end, which specifies that equal objects must have equal hash codes - this isn't automatic, it's by convention so things like HashMap will work.
Comparing hashCode values is NOT the default implementation of equals, and should NEVER be the implementation of equals - it is possible to have multiple non-equal objects with the same result for hashCode. The rule is to make sure your hashCode implementation returns the same value if objects are equal.
As an example, both of these will output the same hashCode, but are clearly not equal:
System.out.println("Aa".hashCode());
System.out.println("BB".hashCode());
Recommended further reading: this related question.
No, .equals() would not magically get overwritten when String are getting compared in list.
the String Class in java already has the .equals() method overwritten in its definition to compare characters by default.
meaning, even without a list if you do this:
String a = new String("abc");
String b = new String("abc");
System.out.println(a.equals(b));
Then, your output would be true
refer this: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html

Do two equal objects have to have the same toString output?

Do two equal objects have to have the same toString output?
In code, does the following have to hold in general?
if(o1.equals(o2))
return o1.toString().equals(o2.toString()) // always true?
I am asking because I have just written a toString method for which the above statement does not hold. I could not find any hint at the documentation, but I want to get sure my toString method does not break any contract rules.
No, they do not have to have the same toString() output in order to be equal. There is no contract in Java that states the equals() method must be true for both the object itself and its toString() method.
The only contract equals() has with other methods is with hashCode():
Note that it is generally necessary to override the hashCode method whenever this method [equals] is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
The contract it has irrespective of other methods is:
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.
Source: https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-
Edit: Some people are saying Effective Java by Joshua Bloch says the toString() method should use the same fields as the equals() method. This is not true. He states:
While it isn’t as important as obeying the equals and hashCode contracts (Item 8, Item 9), providing a good toString implementation makes your class much more pleasant to use.
What he classifies as a "good implementation" is:
When practical, the toString method should return all of the interesting information contained in the object, as in the phone number example just shown. It is impractical if the object is large or if it contains state that is not conducive to string representation. Under these circumstances, toString should return a summary such as “Manhattan white pages (1487536 listings)” or “Thread[main,5,main]”.
So no, it in no way relates to the equals() method.
There is no requirement for this. There is a dependency between equals and hashCode: equal objects must return the same hashCode value. toString is only used for printing the object.
There is no contract for toString, only for equals and hashCode. And from my point of view it also doesn't make sense.
Imagine o1 and o2 are of class Person{}, then you get only the string of the reference.
There's no "requirement" that hashCode match equals, only a best practice that it do so, or your program won't make sense. Same with toString. It should be consistent with equals, as should compareTo if used. See Effective Java by Joshua Bloch for the rationale. People who tell you otherwise need to read that book because they're mistaken.

Objects.equals and Object.equals

I try to create a tuple class that allows a tuple-like structure in Java. The general type for two elements in tuple are X and Y respectively. I try to override a correct equals for this class.
Thing is, I know Object.equals falls into default that it still compares based on references like "==", so I am not so sure I can use that. I looked into Objects and there is an equals() in it. Does this one still compare on references, or it compares on contents?
Quickly imagined the return statement as something like:
return Objects.equals(compared.prev, this.prev) && Objects.equals(compared.next, this.next);
where prev and next are elements of tuple. Would this work?
The difference is the Objects.equals() considers two nulls to be "equal". The pseudo code is:
if both parameters are null or the same object, return true
if the first parameter is null return false
return the result of passing the second parameter to the equals() method of the first parameter
This means it is "null safe" (non null safe implementation of the first parameter’s equals() method notwithstanding).
this is literal code from java source: as you can see, #Agent_L is right
The answer to your question "Does this one [Objects.equals] still compare on references, or it compares on contents?" - Objects.equals does some comparisons on the references but it expects the first argument's class to implement equals() in which the comparison of contents is done as well as on reference.
Your second question about the implementation of equals in your tupple-like class having prev and next as its tupple attributes the answer is: your suggested implementation would work only if
prev and next are primitives or if their type implements equals properly.
So if prev for example is of type Foo, then you can use Objects.equals to test the two Foo's only if class Foo implements equals as expected.
Objects.equals just calls it's first arguments .equals method. In java, if you want to be able to test for equality in instances of a class you made, then you have to override the equals method. instance.equals() only uses == if that instances type doesn't override the equals method.

Comparing 2 Points - java

I've noticed that you can't compare 2 points like this:
if (pointOne == pointTwo) { }
I always have to do it like this:
if (pointOne.x == pointTwo.x && pointOne.y == pointTwo.y) { }
I really wonder why you can not use the first example, does anyone have an answer?
You must use the equals method of class Point. Check this.
If you use == what you are actually doing is checking if the memory address of the two Point objects is the same.
In Java, all classes are derived from Object, and you can override the equals method, providing a convenient way of checking if in fact, two objects of the same Object derived class, are the same.
== operator checks both reference pointing to the same object or not.
You should use equals method of Point object -
pointOne.equals(pointTwo);
Determines whether or not two points are equal. Two instances of
Point2D are equal if the values of their x and y member fields,
representing their position in the coordinate space, are the same.
Documentation
Because the Point is reference, and if you need to use equals, you need to override the method equal. Java doest not support override operators like "==".
I assume pointOne and pointTwo are objects of some class? You cannot overload operators in java, that is why you have to compare fields.
In such cases it is a good practive to override the equals method for your class and use it this way:
PointOne.equals(PointTwo)
Well this will be an object comparison. You would be comparing memory locations if you compare using ==.
You could override and call Equals.
You can use your first example because running pointOne.x == pointTwo.x compares the primitive types (int) which the == operator is capable of.
When you run pointOne == pointTwo you're comparing the Point object references, which they're not.
As others have said, you can use pointOne.equals(pointTwo)

Java: If I overwrite the .equals method, can I still test for reference equality with ==?

I have the following situation: I need to sort trees based by height, so I made the Tree's comparable using the height attribute. However, I was also told to overwrite the equals and hashCode methods to avoid unpredictable behaviour.
Still, sometimes I may want to compare the references of the roots or something along those lines using ==. Is that still possible or does the == comparison call the equals method?
equals() is meant to compare an object with rules set by the programmer. In your example you compare your trees by height, so you'll write equals() so it compares heights.
==, as you said, compares references. These aren't touched neither by equals() nor by hashCode(). So you won't change its behaviour.
Yes, == will not call hashCode or equals. You can still test for reference equality like this.
== does not call equals. So it's still find for identity checks.
As many implementations of equals start with this == other check you would get a literal StackOverflow if it were calling equals behind the scenes.
I think that a bigger question here is whether it is appropriate to implement comparable on these objects. It may be more appropriate to use a Comparator for the operations that work on height, and not embed ordinal computation in the class itself.
My general philosophy on this is to only implement Comparable if there is a truly natural ordering for the object. In the case of a tree node, is height the only way that anyone could ever want to sort? Maybe this is a private class, and the answer is 'yes'. But even then, creating a Comparator isn't that much extra work, and it leaves things flexible in case you decide you want to make that tree node a protected or public class some day.
== tests referential equality. It will not call equals.
Overriding the equals() method will have NO effect on the == operator.
== is used to test if 2 references point to the same object.
equals() method "meaningfully" compares 2 objects.
It is important to realize the implication of the work "meaningful" here. Equality is easier to understand when you are comparing, for instance, 2 Strings or 2 integers. This is why, the equals() method - inherited from the Object class - is already overridden by the String and Wrapper classes (Integer, Float, etc). However, what if you are comparing 2 objects of type Song. Here, equality can be established on the basis of
1) Artist name
2) Song name
3) or some other criterion
Therefore, you have to override the equals() method to "explicitly" determine "when" 2 Song objects are considered equal.
The "unpredictable behavior" you mentioned in your question relates to objects like the one above (Song) behave when dealing with Collections like Map. You SHOULD NOT use these objects in a map until you override both the equals() and hashcode() method. The reason being how hashmap search and indexing works. Refer the JavaDoc for the specifc rules. What you should remember is:
If 2 objects are meaningfully equal, their hashcode should return the same value. However, it is not necessary for 2 objects to be equal, if they return the same hashcode. Again, Java doesn't enforce any rules regarding this. It is your responsibility to implement the equals() and hashcode() methods correctly.

Categories

Resources