What's faster, object = = object or object.equals(object)?
Which one applies to my code?
Why do they return the same result sometimes and not others?
Are there systemic exceptions?
Some quick things:
* The "= = " operator returns true if the variables on each side of the operator point to the exact same exact object in memory.
* Some objects are kept in pools for optimization and the system skirts some "rules" to make things go better/faster - example, String objects
At the java.lang.Object level, .equals(Object) simply does this type of activity in its code (pseudo-code):
return this == someObjectPassedIn;
Also, at its elemental level, the = = operator is fundamental and very fast. And, if one's class hierarchy does not override .equals(Object), then .equals(Object) is also very fast.
If any object in the hierarchy of a given variable reference overrides .equals(Object), then it is possible that the .equals(Object) may be some amount slower, depending on what the override does.
For example:
Here’s something (pseudo-code!!!!) that causes a more expensive .equals(Object) method execution:
---snip---
public class SlowEquals extends Object {
//here, we declare 13 different instance variables to make up
//the state of this object… they’re Strings, Vectors, whatever is required for the design…
private Vector someEmployeesOrSomething = new Vector();
private String title = null;
//…etc, lots more declarations
//here we would have accessor behavior, like getSomeEmployeesOrSomething() here…
public Vector getSomeEmployeesOrSomething(){
return someEmployeesOrSomething;
}
//now, we override .equals(Object) because we want to see if the
//objects are virtually the same data, for example
public boolean equals(Object anObject){
//here we go out fast when any of the state is diff than the same as us
//plus we check to do some basic logic
//if it is me, don’t waste cycles comparing my state, fall out
if(this == anObject){
return true;
}
//is it even the same class as me?
//If it isn’t - fall out, if it is, then compute my state
if( anObject instance of getClass()){ //remember, pseudo-code hee!
//if it’s not the same object in memory, then compare state
//here’s where things slow down from == a lot!
//compare each of this object’s state to the passed in object’s state
SlowEquals comparisonObject = (ComparisonObject)anObject;
if(! comparisonObject.getSomeEmployeesOrSomething()).equals(getSomeEmployeesOrSomething()){
return false;
}
//… repeat for every memember of my state, return false on any difference
}
//if we hit here, return false as a last and default case
return false;
}
}
---snip---
In many cases, developers do not override .equals(Object) in their object specializations, and in those cases, it is safe and fast to do .equals(Object). On the same side of the coin, if the developer has overridden .equals(Object), it is sometimes likely they meant for it to be used, regardless of cost: the object is saying that it wants to be compared in a very specific way.
What about String objects, you say? Strings are largely (sometimes entirely) pooled for performance and memory conservation
If the JVM supports it (MOST of the time, they do), String pooling is a technique whereby strings created during a program's execution are stored and used as actual object in memory for many variable references.
For example, if String pooling is supported (again, MOST of the time):
String myName1 = "TigrisDevelopus";
String myName2 = "TigrisDevelopus";
In this snippet of code, both of the following return true:
myName1 = = myName2; //true
and
myName1.equals(myName2); //true
This is true, even though there is no myName1 = myName2 line of code.
Inversely, the following would not work like String pooling: the code would make reference to two different object in memory:
Employee myEmployee1 = new Employee("Doe", "Jane");
Employee myEmployee1 = new Employee("Doe", "Jane");
myEmployee1 = = myEmployee1; //returns false
Whether or not .equals(Object) would return true would depend on whether or not Employee (or any of its parent classes) overrides .equals(Object) and looks at the value of the String passed in to the constructor.