Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Should equals() and compareTo() be equivalent to test for equality ??

Reply
Thread Tools

Should equals() and compareTo() be equivalent to test for equality ??

 
 
Neroku
Guest
Posts: n/a
 
      01-25-2007
Well, I know equals() and compareTo() could behave different to test
for equality, it just depend on the way I implement them, but, Would it
be a bad practice to rewrite equals() and compareTo() so they behave in
the following way:

- Two different instances of the same class hold different attribute
values, calling equals() return false comparing both objects because
they are not the same, but compareTo() return 0, since this is the
sorting criteria I want (a desired attribute match).

or even

- Two different objects of the same class hold the same attribute
values, this is, they are internally equals, and calling equals()
return false because the are different instances (the references are
not the same), but calling compareTo() return 0, since all attributes
contain the same value.


Thanks in Advanced

 
Reply With Quote
 
 
 
 
Ingo Menger
Guest
Posts: n/a
 
      01-25-2007


On 25 Jan., 12:52, "Neroku" <n37...@gmail.com> wrote:
> Well, I know equals() and compareTo() could behave different to test
> for equality, it just depend on the way I implement them, but, Would it
> be a bad practice to rewrite equals() and compareTo() so they behave in
> the following way:


Sure. No matter how you define equality, the following should always
hold:
a.equals(b) == (a.compareTo(b) == 0)

Note that certain standard classes deviate from this ideal, i.e.
BigDecimal.

 
Reply With Quote
 
 
 
 
Gordon Beaton
Guest
Posts: n/a
 
      01-25-2007
On 25 Jan 2007 03:52:19 -0800, Neroku wrote:
> Well, I know equals() and compareTo() could behave different to test
> for equality, it just depend on the way I implement them, but, Would it
> be a bad practice to rewrite equals() and compareTo() so they behave in
> the following way:


To test for identity (i.e. reference equality), use ==, not equals().

I would find it extremely confusing if compareTo() returned 0,
indicating that the elements are equal in sort order, but equals()
returned false. If the objects represent the same *value*, then they
are *equal*.

/gordon

--
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
 
Reply With Quote
 
Tom Hawtin
Guest
Posts: n/a
 
      01-25-2007
Neroku wrote:
> Well, I know equals() and compareTo() could behave different to test
> for equality, it just depend on the way I implement them, but, Would it
> be a bad practice to rewrite equals() and compareTo() so they behave in
> the following way:


The JavaDocs and I strongly recommend that compareTo be consistent with
equals (and hashCode). In theory it shouldn't actually make any
difference (other than for one of the concurrent collections in 1.5 (not
1.6)). However, as a programmer, I would find it 'surprising'.

IMO, natural ordering should be considered an implementation artifact.
String is Comparable, for instance, but the order makes no sense. It
sorts case sensitive, and doesn't even account for code points above
0x10000.

> - Two different instances of the same class hold different attribute


The value of the fields are irrelevant. Try to think in terms of what
the object actually represents.

Tom Hawtin
 
Reply With Quote
 
Ingo Menger
Guest
Posts: n/a
 
      01-25-2007


On 25 Jan., 13:08, Tom Hawtin <use...@tackline.plus.com> wrote:

> IMO, natural ordering should be considered an implementation artifact.
> String is Comparable, for instance, but the order makes no sense.


It's not supposed to.

> It sorts case sensitive,


Yes, that's because it's supposed to be well defined, and this means,
for instance, that "WELL DEFINED" must be either greater or less than
"well defined", since it's not equal. But it can't be equal, because it
can be observed, that it's different.
(One could make this observation impossible by assigning upper case
letters the same code points as lower case letters, of course. I don't
think this would not be very practical, to say the least.)

> and doesn't even account for code points above
> 0x10000.


Is that so?
That's bad, of course. But I think most people really don't care about
those.
After all, for many decades, it didn't account for code points above
0xff. And it was not that bad.

 
Reply With Quote
 
Chris Uppal
Guest
Posts: n/a
 
      01-25-2007
Neroku wrote:

> Well, I know equals() and compareTo() could behave different to test
> for equality, it just depend on the way I implement them, but, Would it
> be a bad practice to rewrite equals() and compareTo() so they behave in
> the following way:
>
> - Two different instances of the same class hold different attribute
> values, calling equals() return false comparing both objects because
> they are not the same, but compareTo() return 0, since this is the
> sorting criteria I want (a desired attribute match).


I would say that in general it's a bad idea for compareTo() not to be
compatible with equals(). As others have said, it's not what they'd expect to
see, and that's always something to avoid if you can.

There may be sufficient reasons to break that rule (though I can't think of an
example off the top of my head). Remember that you have the option of using a
custom Comparator for your objects instead of the natural ordering implied by
compareTo(). If the "odd" comparison order is particularly natural (despite
it's oddness or likely to be needed in several places, then I would make
the special Comparator implementation a class statically nested within the main
object class. Quite possibly the Comparator would be stateless in which case
you could have a single, immutable, public instance of the Comparator available
for convenient use.

-- chris


 
Reply With Quote
 
Andreas Leitgeb
Guest
Posts: n/a
 
      01-25-2007
Gordon Beaton <> wrote:
> To test for identity (i.e. reference equality), use ==, not equals().
>
> I would find it extremely confusing if compareTo() returned 0,
> indicating that the elements are equal in sort order, but equals()
> returned false. If the objects represent the same *value*, then they
> are *equal*.


100% agree.

If the originator of this threads really needs an ordering
that is inconsistent with .equals(), there is also the path
of deriving a class from "Comparator", and pass that
to most of the sorting-methods offered by the Class
library. IOW, most methods that depend on an ordering
have an overloaded variant that accepts a separate
Comparator.

 
Reply With Quote
 
Tom Hawtin
Guest
Posts: n/a
 
      01-25-2007
Ingo Menger wrote:
>
> On 25 Jan., 13:08, Tom Hawtin <use...@tackline.plus.com> wrote:
>
>> IMO, natural ordering should be considered an implementation artifact.
>> String is Comparable, for instance, but the order makes no sense.

>
> It's not supposed to.


Yes. I'm trying to say that there is no point attempting to make the
natural order make any sense.

Whilst you might make a Comparator differ from equals (the JavaDocs say
use caution), it doesn't matter with Comparable. Give it any old order.
The natural order is for algorithms such as TreeSet, not to define an
ordering for presentation purposes. Making compareTo give a meaningful
result is like trying to do the same with hashCode.

Tom Hawtin
 
Reply With Quote
 
Ingo Menger
Guest
Posts: n/a
 
      01-26-2007


On 25 Jan., 20:38, Tom Hawtin <use...@tackline.plus.com> wrote:
> Ingo Menger wrote:
>
> > On 25 Jan., 13:08, Tom Hawtin <use...@tackline.plus.com> wrote:

>


> The natural order is for algorithms such as TreeSet, not to define an
> ordering for presentation purposes. Making compareTo give a meaningful
> result is like trying to do the same with hashCode.


Exactly, apart from numbers, where the meaning is the mathematical one.

 
Reply With Quote
 
Tom Hawtin
Guest
Posts: n/a
 
      01-27-2007
Tor Iver Wilhelmsen wrote:
> Gordon Beaton <> writes:
>
>> I would find it extremely confusing if compareTo() returned 0,
>> indicating that the elements are equal in sort order, but equals()
>> returned false. If the objects represent the same *value*, then they
>> are *equal*.

>
> Countercase: You have a Customer class you want to sort (the function
> of Comparable) by last name then first name. And then you get two
> customers called Joe Jackson. But you use a persistence framework so
> you need to use equals() and hashCode() on some unique key (like a
> customer number). So equals() will return false for the two Joes, but
> compareTo() will return 0.


It's a bad idea to use natural ordering for presentation. Use a
Comparator instead.

If you put your customers in a TreeSet (with natural ordering), you
wouldn't get them all back out.

Tom Hawtin
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
test for list equality noydb Python 18 12-16-2011 07:32 AM
Compile time equality test Alan Woodland C++ 1 07-10-2007 11:09 AM
Test equality of each element in an array 12 34 Ruby 15 07-03-2007 01:48 AM
Should hash equality ignore default values ? Tomasz Wegrzanowski Ruby 1 05-08-2007 12:10 AM
test test test test test test test Computer Support 2 07-02-2003 06:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57