In general, the answer to your question is "yes", but...
.equals(...)will only compare what it is written to compare, no more, no less.- If a class does not override the equals method, then it defaults to the
equals(Object o)method of the closest parent class that has overridden this method. - If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the
Object#equals(Object o)method. Per the Object API this is the same as==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality. - Always remember to override
hashCodeif you overrideequalsso as not to "break the contract". As per the API, the result returned from thehashCode()method for two objects must be the same if theirequalsmethods show that they are equivalent. The converse is not necessarily true.
In general, the answer to your question is "yes", but...
.equals(...)will only compare what it is written to compare, no more, no less.- If a class does not override the equals method, then it defaults to the
equals(Object o)method of the closest parent class that has overridden this method. - If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the
Object#equals(Object o)method. Per the Object API this is the same as==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality. - Always remember to override
hashCodeif you overrideequalsso as not to "break the contract". As per the API, the result returned from thehashCode()method for two objects must be the same if theirequalsmethods show that they are equivalent. The converse is not necessarily true.
With respect to the String class:
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".
As with any explanation, let it sink in.
I hope this clears things up a bit.
Videos
I'm currently working on a project that involves comparing strings, but I keep getting stuck on whether to use the "==" operator or the ".equals()" method. From what I've gathered so far, they seem to do the same thing - is it true? Or are there cases where one should be used over the other?
I'm on MOOC.fi and I'm a little confused on why you can't use .equals() when comparing two objects. And on part 5_12.Song programming exercise, I'm confused on why the parameter takes an Object parameter instead of a "Song" type, and then why do we have to typecast the object to compare it?
Yes, == with objects is a reference comparison* (checks if the operands are references to the same object), while equals is whatever the class involved defines it to mean (within the requirements documented for equals). Some classes define equals as being the same as ==, including Java's arrays. (Because they don't override the default implementation from Object.equals, which uses ==.)
If you want to compare Java arrays based on the equality of their contents, you use Arrays.equals instead.
Your experiment would have worked if you used a class that defined equals in a useful way, you were just unlucky picking arrays. It's a bit tricky to find a class in the JVM to use for this experiment, because so many either don't implement equals (like arrays) or could be confusing because there are several immutable classes which may reuse instances (although not if you explicitly use new; but I don't want to go down a path of having you use new with something you probably shouldn't, like String; more on that here). I'm going to give up on picking a good example and use the slightly old class SimpleDateFormat:
DateFormat a = new SimpleDateFormat("yyyy-MM-dd");
DateFormat b = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(a == b ? "== Same" : "== Different");
System.out.println(a.equals(b) ? "equals Same" : "equals Different");
That outputs
== Different equals Same
because SimpleDateFormat defines equals to check that the other object is also a SimpleDateFormat with the same formatting.
Live example
Re your comment on the question:
I have someone the answer points but I only get the == part, if .equals is checking the content, how come the code didnt print "same" for the second if
Because equals doesn't, necessarily, check content. It only does if a class overrides the default Object.equals (which just uses ==) and implements a content check. Arrays don't. (One could argue that they should have, but they don't.) Other classes, like SimpleDateFormat and String and Integer and HashMap do.
In essence: == is always a reference comparison. equals may or may not be a contents comparison, depending on what class you're using it on.
So for instance, say we have this class:
class Example1
{
private int content;
Example1(int content) {
this.content = content;
}
public static void main (String[] args) throws java.lang.Exception
{
Example1 a = new Example1(42);
Example1 b = new Example1(42);
System.out.println(a == b ? "== Same" : "== Different");
System.out.println(a.equals(b) ? "equals Same" : "equals Different");
}
}
Since that class doesn't override equals, you'll get the same answer ("Different") for both == and equals. Live Example.
But if we override equals to define what it would mean for two instances to be equal (in this case: because they have the same content):
class Example2
{
private int content;
Example2(int content) {
this.content = content;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !obj.getClass().equals(this.getClass())) {
return false;
}
Example2 other = (Example2)obj;
return this.content == other.content;
}
@Override
public int hashCode() {
return this.content;
}
public static void main (String[] args) throws java.lang.Exception
{
Example2 a = new Example2(42);
Example2 b = new Example2(42);
System.out.println(a == b ? "== Same" : "== Different");
System.out.println(a.equals(b) ? "equals Same" : "equals Different");
}
}
Now equals says two instances with the same content are the same, because the class defines what that means. Live Example. (Also note that when overriding equals, you must override hashCode, which is why I've done so above.)
* More generally, == tests if the values of its operands are the same. The value in the case of reference types is an object reference, and two object reference values are only the same when they refer to the same object are are only different when they refer to different objects (or one of them is null; not referring to an object at all).
To create object you need some portion of memory to store it.
Operator == checks if two variables point to the same memory block. That is they points to the same object instance (they are one person under different aliases).
equals() is a method and checks equality by some algorithm. Meaning two object contain the same data (they are different persons but with the same face, twins for example). Default implementation for java.lang.Object#equals is
public boolean equals(Object obj) {
return (this == obj);
}
Using you IDE you can ensure that equals for an array is actually java.lang.Object#equals. To check two arrays for equality you should use Arrays.equals. It has also a lot of other useful methods for manipulating with arrays. It is a good idea to check this class first when you need to do something with an array. It saves much time and code lines.
EDITED
Arrays (int[], float[], String[], AnyClass[]) does not implement custom equals method. So for array and for any your custom class equals() and == do same operation unless you override equals() and provide custom comparison. Like
public class Person {
public String name;
public String surname;
public Person(String name, String surname) {
this.name = name;
this.surname = surname;
}
public boolean equals(Object thatObj) {
if (thatObj instanceof Person) {
Person that = (Person) thatObj;
return this.name.equals(that.name) &&
this.surname.equals(that.surname);
}
return false;
}
}