• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Q. equals and ==

 
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I did an exam on the www.certification4career.com, but I've got some doubts about the answers given. Can someone help me with this?
Mock Exam

Answer. A and B
Shouldn't the answer be B and C? Because, When the equals() method is not overridden, it is identical to the == operator (it compares two reference variables)?
[ April 28, 2003: Message edited by: Karin Paola Illuminate ]
 
author
Posts: 9050
21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Karin -
I'd say it's a poorly written question. The question should state whether equals() has been overridden. Your point is good.
If the question said 'and equals has been properly overridden', then what do you think the answers would be?
[ April 28, 2003: Message edited by: Bert Bates ]
 
Karin Paola Illuminate
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Aha... I understand... If it is properly overridden the equals() method will compare content.
 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would say only B is correct. The equals method when overridden does whatever the implementer makes it do. Comparing content is one possibility, but not the only one.
 
Ranch Hand
Posts: 716
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But the purpose of equals() is to do a deep compare, so assuming that it's a proper implememtation and not merely a return true, A and B will be correct...
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am curious to know if you would call the example below �comparing the content�?
 
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Marlen,
Your code example shows something I have tried to explain in an other posting before.
You have to make a distinction between the rules for equals overriding and the purpose of equals overriding.
The rules specify the necessary conditions for equals overriding.
This means: if any rule is violated the equals override is not valid.
But the rules are not a suffient condition.
Logically suffient condition means: if all conditions are met, then we have proof that the equals override is valid.
Your example shows that we can construe an equals override that returns true while the state of objects is different and at the same time no violation of the rules of equals overriding.
Similar programs can be construed or even weirder and they do not violate any rule of equlas overriding .
However these equals methods violate the purpose of overriding: to compare objects to check if they meaningfully euquivalent.
Meaning: to check if the state of one object is equal to the state of an other object.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is what I am trying to do in my example.
Pick your favorite (small) integer, for example 5.
Now organize all of the integers into 5 disjoint sets:
{... �5, 0, 5, 10 ...}
{... �4, 1, 6, 11 ...}
{... �3, 2, 7, 12 ...}
{... �2, 3, 8, 13 ...}
{... �1, 4, 9, 14 ...}
Each object of class C holds an integer.
Define equality this way:
Two objects of class C are equal if the integer they hold are in the same set.
It�s not an unreasonable definition. The Object API says equals has to satisfy an equivalence relation. So I defined an equivalence relation on the set of integers.
I was wondering whether you would call this definition of equals �comparing the content�.
I am *using* the content of the objects to compute equality. But I am not sure whether I am *comparing* the content.
 
John Zoetebier
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


It�s not an unreasonable definition. The Object API says equals has to satisfy an equivalence relation. So I defined an equivalence relation on the set of integers.


The set of integers violates an other rules, not explicitly stated in the API, which is called "principium sparsimonium".
In simple terms: if 1 rule is valid, we should not use 2 rules.
In your code example the state of the object should be represented only by the integer i.
We can compare objects simply by comparing this integer, no more, no less.
Anything else just blurs the subject and the purpose of hashing.
This is the reason why your code example is not a valid implementation for hashing purposes.
Let us take one step back.
What are we trying to achieve with all this equals and hascode stuff ?
It solves only one purpose: to get our object back in an efficient way from a hashing collection once the reference to the original object is lost.
After loosing the reference the only thing we can do is compare an object with an object in the collection to see if they are "equal".
Now comes the tricky bit: what is equal.
What the designers could have done is provide a definition of what object equivalence means rather than give a set of impelmentation guidelines.
These guidelines (rules) give an impression of completeness, but in fact are not, as your program shows.
For example a definition of object equivalence could be:


Object A and object B are meaningful equivalent if the state of object A is equal to the state of object B.
The state of an object consists of the set of all member fields of an object.


All rules stated in the API follow from this definition.
For example the reflexive rule:
If A is the set of fields of object x of class C, then:
x.equals(x) is true, because (A == A) is true
The definition allows to use a substitution key similar as a record key used for record lookup in a relational database.
This definition would exclude your code example as being valid because variable n is not part of the state of an object of class C.
Variable n is introduced to test the boundaries of the present rules in the API. It has nothing to do with comparing objects based on their state.
 
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your definition is way to constricting. I can see a need in many applications where two objects are equal only if one field is equal to another and other fields are irrelevant. Plus the overhead of testing every field in a class for equivalency can be quite expensive especially if the other fields are objects. Equivalency, in my opinion, is a business rule. If two objects can be used interchangeably within a system then they are equivalent for purposes of that system.
 
Author
Posts: 81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Marlene, your example will fail the symmetric test in the following case
C c1 = new C(20, 5);
C c2 = new C(25, 3);
System.out.println(c1.equals(c2)); // (Math.abs(20-25) % 5) == 0 true
System.out.println(c2.equals(c1)); // (Math.abs(25-20) % 3) == 0 false
because in the equals method you are not taking into consideration 'n' from the other object. But it can pass the symmetric test too if you add the following check
if (this.n != other.n) return false;
As to answer your question, is this considered "comparing the content"?
Yes it is. You are comparing its content.
But, is it valid?
Depends on what do you want to use it for. It is a valid equals() implementation (provided you rectify that 'n' related error.)
And, is it useful? (for collections?)
Depends on how you use it. For collections, it is not useful as it stands. But if you provide an implementation for hashCode() that gurantees same values for two equals objects, it will be useful (assuming that you consider the pairs (20,5) and (25,5) as equivalent when using a hashtable.)
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you John, Thomas and Jignesh for taking the time to think about my example and to explain your reactions.
I was trying to give an example where the equals method does not compare the content of two objects. I was trying to define the group of integers modulo n as objects. It didn�t work.
Jignesh, you are correct about the symmetry error and the fix and the missing hashcode method.
 
John Zoetebier
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Your definition is way to constricting. I can see a need in many applications where two objects are equal only if one field is equal to another and other fields are irrelevant.


The definition is not too constricting at all.
The definition states in a more formal way what object equivalence is about: that ALL fields in an object are exactly equal between the object in the hashing collection and the object we search for.
What happens in practice is similar to what happpens when looking up a record in a relational database: you use a key field in stead of searching for [B]all[/B} fields in the record.
This is a matter of efficiency that has nothing to do with the validity of the definition.
In the context of objects you can have a key which uniquely identifies 1 particular object. If the key is equal, then all other fields will be equal as well. If this is not true, the field is not a valid key.
 
John Zoetebier
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jignesh says:


Marlene, your example will fail the symmetric test in the following case
C c1 = new C(20, 5);
C c2 = new C(25, 3);
System.out.println(c1.equals(c2)); // (Math.abs(20-25) % 5) == 0 true
System.out.println(c2.equals(c1)); // (Math.abs(25-20) % 3) == 0 false


The example of Marlene uses a constant seed value,for example 5, to generate the object content of field "i"
Using the same constant value, the equals method passes the symmetric test.


As to answer your question, is this considered "comparing the content"?
Yes it is. You are comparing its content.


There are a number of problems with stating that this method is comparing the content.
1)
The seed value, in this case 5, is not part of the object content.
If it is part of the object content, we can add an arbitary number of other variables to the equation and all of them woud be part of the object content. This makes it impossible to state what is part of the content and what not.
2)
The following object are equal according to this implementation of equal
C c1 = new C(20, 5);
C c2 = new C(25, 5);
When we add both object to a collection, we cannot predict which object the collection will return as both are equal. Even worse, while we are adding more and more of "equal" object to the collection ,the collection can return any one of these objects while we search for the same object each time.
This behaviour is not predictable from a programmers point of view.
This behaviour is not what you may expect from a well-behaved collection.
3)
Last but not least.
There is no formal definition in the API of "object equivalence", nor of "object content"
The result is that we try to convince each other about the validity of our interpretation of the rules, which can be interesting, but is not very productive.

But, is it valid?
Depends on what do you want to use it for. It is a valid equals() implementation (provided you rectify that 'n' related error.)


Even without formal definition, we can look at it from a practical point of view: does a collection return the same object each and every time when are looking up the same object.
What else can the purpose be of the equals method override than return the same object?
A collection that returns a different object on successive calls is not a valid implementation from this point of view.


And, is it useful? (for collections?)
Depends on how you use it. For collections, it is not useful as it stands. But if you provide an implementation for hashCode() that gurantees same values for two equals objects, it will be useful (assuming that you consider the pairs (20,5) and (25,5) as equivalent when using a hashtable.)


Is a collection that returns one moment one object and another moment an other useful ?
I really doubt if there is any practical purpose for a collection that exhibits this kind of unpredictable behaviour from a programmers point of view.
 
Ranch Hand
Posts: 72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
Firstly i think answer is A,B,C because equals method looks for reference and content.
Confused my self !!

Originally posted by Karin Paola Illuminate:

Answer. A and B
Shouldn't the answer be B and C? Because, When the equals() method is not overridden, it is identical to the == operator (it compares two reference variables)?
[ April 28, 2003: Message edited by: Karin Paola Illuminate ]


I was confused by your above statement, I thought when we use == operator, it will look for the operands content and not the reference. And if we use equals operator, it will look for the reference and also the content. Even though we dont override equals.
The statement you made it is telling that if we don't override the equals method then it only operators like == operator. i.e. it will search for content of both operands but not the reference.
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi all.
If Marlene has defined that new C(20, 5); and new C(25, 5); objects are equivalent, then it is fine that a collection returns either of both. It is wierd, but ok if this was the intention.
Yes I agree about the symmetry error.
"Comparing content" does not mean to compare systematically all the fields of the object, but only those that are relevant for the equivalance relationship. This matter must be decided by the programmer.
 
Jignesh Malavia
Author
Posts: 81
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Zoetebier:
Is a collection that returns one moment one object and another moment an other useful ?
I really doubt if there is any practical purpose for a collection that exhibits this kind of unpredictable behaviour from a programmers point of view
When we add both object to a collection, we cannot predict which object the collection will return as both are equal. Even worse, while we are adding more and more of "equal" object to the collection ,the collection can return any one of these objects while we search for the same object each time.
This behaviour is not predictable from a programmers point of view.
This behaviour is not what you may expect from a well-behaved collection


John, I think there is some misunderstading about the collections framework. The collections classes use hashCode() as a first step for fast search and retrieval. If we do not implement the hashCode() at all, then by default all objects return a different value for hashCode. If the hashCode() hashes into a different bucket, then the equals() method is never called.
The collections classes use equals() method as a second step, only if the first step hashes into the same bucket. If equals() also returns true, the collection assumes that the objects are identical or atleast "interchangeable". So if we implement both, hashCode() and equals(), properly, then a collection class such as a List will consider them as interchangeable and will not accept two entries.

Originally posted by John Zoetebier:
Even without formal definition, we can look at it from a practical point of view: does a collection return the same object each and every time when are looking up the same object.
What else can the purpose be of the equals method override than return the same object?
A collection that returns a different object on successive calls is not a valid implementation from this point of view


As Thomas and Jose already said, if the business rules dictate that two objects with different content can be considered as equal, then the collections must treat them as inter-changeable. Repeating myself, I just want to add to it that when using the collections if we implement the equals() method but do not implement the hashCode() method according to the rules of the API, then all bets are off!
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Zoetebier:
In the context of objects you can have a key which uniquely identifies 1 particular object. If the key is equal, then all other fields will be equal as well. If this is not true, the field is not a valid key.


What's the key field for a JButton? Most classes do not have a key field.
[ April 29, 2003: Message edited by: Thomas Paul ]
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Zoetebier:
A collection that returns a different object on successive calls is not a valid implementation from this point of view


Here's an example that always returns the same object:

In this implementation, since every AlwaysEquals object is equal to every other AlwaysEquals object there is only one object in the HashMap (size = 1). So there is only one AlwaysEqual object in the HashMap and every put with an AlwaysEqual object replaces the one in the HashMap. You can use any instance of AlwaysEqual to get that one entry. An odd implementation but it violates no rules.
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I haven�t had the time yet to work through all the ideas presented above, so this is not a reply. Instead, I would like to throw one more thing into the mix.
I have much respect for Joshua Bloch. He must be a very talented person, judging from his academic and professional credentials, his book Effective Java and his source code in java.util.* (such as LinkedHashMap.java). In Effective Java, he devotes 10 pages on overriding the equals method.
Notice that Bloch never describes equality relative to the content of an object.

So when is it appropriate to override Object.equals? When a class has a notion of logical equality that differ from mere object identity, and a superclass has not already overridden equals to implement the desired behavior.


In my opinion, throughout Effective Java, Bloch is articulate and chooses his words carefully. He is rigorous and yet talks in plain English. And he speaks from the point of view of experience.
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Marlene Miller:
In my opinion, throughout Effective Java, Bloch is articulate and chooses his words carefully. He is rigorous and yet talks in plain English. And he speaks from the point of view of experience.


Bloch is very good but he screws up in one area... dealing with overloading methods. He says in item 26: "never export two overloadings with the same number of parameters." This is very bad advice that is thankfully ignored by the API. The println() method for example has been overloaded 19 times with the exact same number of parameters. Imagine how difficult println would be to use if the developers had followed Bloch's advice. We would have one println() method that takes an Object as a parameter and anytime you wanted to print a primitive you would have to wrap it. Would that be easier to understand or use? Is anyone confused by the println() method having so many overloadings?
But generally Bloch is excellent (although I also have some complaints about his enum pattern).
 
Ranch Hand
Posts: 97
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Originally posted by John Zoetebier
The definition states in a more formal way what object equivalence is about: that ALL fields in an object are exactly equal between the object in the hashing collection and the object we search for.


Then consider this example:

Do you consider e1 to be equal to e2 ? or e3? Or should two Equality objects share exactly the same array reference for them to be considered equal ? How would you implement equals() for this class?
I think there is certainly more than one way to do it, and one is not necessarily more correct than the other. I think equivalence is often open to intepretation, and the equals() implementation should be determined by the practical requirements and business rules (and it should meet the reuqirements of the equals() implementation contract).
[ April 30, 2003: Message edited by: Rory French ]
 
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"I can see a need in many applications where two objects are equal only if one field is equal to another and other fields are irrelevant"
an excellent point - equivalence depends on the observer's perspective. therefore, an object's interface for equals probably needs to be observer-sensitive. interesting.
 
You know it is dark times when the trees riot. I think this tiny ad is their leader:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic