I understand that .equals() compares the content of the field, while == compares the hexcode location of an object, but there are still some things troubling me. Specifically, if I want to check for equality of the age of something, would I use == since it is an int and Java would read all equal numbers as the same? I know a String is always compared with .equals(), and a boolean value is compared with ==, but what about doubles, ints, and floats? Let me know if this question is too vague and I will provide some example code. Thanks for your help!
Let's say I have two rolodex cards. You can write the address of a house on each card. The addresses may be the same, or they may be different.
"==" says "is the same address written down on both rolodex cards"
.equals says "are the two houses worth the same amount of money".
Note that if the same address is on both cards, then by definition, .equals will return true. If they are different addresses, we have to compute the value of the home. We can decide if we do that off tax records, if we simply look at the number of square feet, if we look at the number of bathrooms and bedrooms, or if there is some other way that makes the most sense for our situation.
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Brian Mart wrote:I understand that .equals() compares the content of the field, while == compares the hexcode location of an object,
Hmmm, well I've still to meet a 'hexcode location' in Java yet; and I've been using it for 12 years now.
but there are still some things troubling me. Specifically, if I want to check for equality of the age of something, would I use == since it is an int and Java would read all equal numbers as the same? I know a String is always compared with .equals(), and a boolean value is compared with ==, but what about doubles, ints, and floats? Let me know if this question is too vague and I will provide some example code. Thanks for your help!
Not vague at all.
Simple rule: Objects should ALWAYS be compared with .equals(). Primitives must be compared with '==', since they have no equals() method to run.
So, when in doubt: USE equals(). If you get a compiler error that says something like 'no such method' or 'invalid for primitive', try '=='; but NOT before.
Isn't it funny how there's always time and money enough to do it WRONG?
here is another way to think about it. all variables in java hold a number - nothing more. got an int? it holds a number. got a String? it holds a number. Got a FredsSpecialObject? it holds a number.
for primitives, the number it holds is, well, the actual number you care about. an int that represents fredsAge would hold "44".
however, a String variable that represents fredsmiddleName actually holds a number. Java knows that for objects, the number is used to find where in memory "Brian" would be stored. Note that for object references, you can't actually GET that number - Java won't let you have it or see it. The number is strictly used to hold the memory address (more or less) of the object.
using "==" always compares to see if the number is the same. for an int, float, double, and other primitives (note that these all start with a lower case letter), that's easy. 44 will always equal 44.
but for objects, you always want to know if they are functionally equivalent. So for Floats, Doubles, Integers (note capital 'F'...), which are objects, you don't care if the memory address is the same. you care if the functional value it represents is the same. Hence, you'd use equals().
Variables in Java can be either object references (what you referred to as hexcode location), or they can be primitive variables. An object reference should NEVER be thought of as in int. It's an address and that's all the Java programmer needs to know about it. Ints are numbers that can be operated on with * - / * etc. You can't do that with object references in Java (thank Gosling).
'==' is an operation that compares two object references to see if they refer to the same object. '.Equal' compares primitive values of objects to see if they are the same.
Now, two object references (A & B) can refer to different objects. In which case A==B would return FALSE. However, if all of the primitive variables in both A and B had been set to the same values, then A.Equal(B) would return TRUE, because .Equal is comparing the primitive contents of the objects. (Damn, I hope I got that right.)
I think some of the replies have been misleading, particularly the one about rolodex cards. Here is my take on your question.
The == operator and the equals() method do very different things. For the primitives (not including String, which is an object often mistaken for a primitive), == is all you can use.
For two object variables o1 and o2, the == operator will tell you if they point to the same object. If you were to code
then (o1 == o2) would return true.
The equals method tells you if two objects have the same contents. The definition of this depends on the class itself; for example, you could decide that an object representing a person was equal if all the name fields were equal, even if the object contained address information as well.
A word of caution if you play with this using Strings -- string literals in Java have rules that make it difficult to predict some things. Based on what I've said, you might expect:
to give you a situation in which o1 == o2 would be false. But it isn't, because the Java compiler remembers that you've already used the literal once, so it assigns a reference to one literal to both variables, making == for them true.
Playing with it using your own class would be preferable. And I think it's less confusing to think of it without the "hex code" or "address of the object" kind of explanation, myself.
I am genuinely curious as to why you think my rolodex card example is misleading. I'm open to criticism, but simply saying "That isn't valid" doesn't really help.
For example, I don't think this is necessarily true:
The equals method tells you if two objects have the same contents.
The equals method can do whatever someone decides it should do. Maybe the object have same contents. Maybe the objects are prizes that evaluate to the same dollar amount. Maybe they are two students who have the same GPA, even though they both took different classes.
The point is...the equals method should be written in such a way that makes sense for the things you want to compare, in the way you need to compare them.
Joined: May 29, 2005
I think it is misleading because there is not enough support for a novice
to understand the parallels between the problem and the example. What is
it that represents the objects? What does the house price have to do with
anything? Why the price? My first thought was that the rolodex cards
were the objects, then I realized that wouldn't work, but only because I
already understood the concepts.
If you had supported it better, it might have worked: "Consider a House
class, instances of it as houses for sale, and rolodex cards as
object variables. It seems clear that any house has one and only one
address, and if two cards carry that same address, they're referring to
the same house. That's the equivalent of an == operator.
"Let us further suppose that you, as a house buyer, think that the
important things about houses are their neighborhoods and their prices. A
program dealing with houses could implement an "equals()" method on a
House class that compared two house variables on these criteria and
returned true if the criteria matched.
"So two rolodex cards could carry houses that passed equals(), but not ==.
Incidentally, the reverse cannot be true - if two objects pass ==, they
are supposed to also pass equals()."
And you are right, equals() can be defined to mean different things; my statement
could be taken to mean that ALL contents are compared, and you are right
that isn't true. In the house example, equals doesn't take into account
whether it is brick or shingle or siding; if houses have the same defined
equivalence the other things can be unequal.
Ralph Cook wrote:And you are right, equals() can be defined to mean different things...
Actually, there are many issues with equals(), not just its meaning; which is why I usually just say "ALWAYS use equals()" to beginners.
Its much easier to work out when you can't use it; and it's a lot better than getting into the bad habit of using '==' when you shouldn't.
In fact, I kind of wish they'd make it a compiler warning when it's used on objects.