GeeCON Prague 2014*
The moose likes Beginning Java and the fly likes Writing a compareTo() method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Writing a compareTo() method" Watch "Writing a compareTo() method" New topic
Author

Writing a compareTo() method

Ken Austin
Ranch Hand

Joined: Aug 20, 2012
Posts: 39

Hello, all. A quick question about writing a compareTo() method...

In the text I'm using, the author says the following:
The String class implements the interface Comparable<String> and defines compareTo in a reasonable way. In this case, the return value of compareTo is zero if and only if the two strings that are being compared are equal. (It is generally a good idea for the compareTo method in classes that implement Comparable to have the analogous property.) If you define your own class and want to be able to sort objects belonging to that class, you should do the same.

He then gives an example of a handwritten compareTo method for comparing people's full names.

After looking at the code snippet and the preceding and following paragraphs several times, I'm not sure what he means by "to have the analogous property." Does anyone want to take a crack at explaining what he's getting at there?
dennis deems
Ranch Hand

Joined: Mar 12, 2011
Posts: 808
It merely means that when you write an implementation of compareTo, you should return 0 only if a comparison of the two objects using equals returns true, just as we observe in the String class.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

It's not very clear, I'll grant you that. On the surface, it sounds like he's saying that, just like String, when you write your compareTo() for your own class, it should only return zero of the two objects being compared are equal. But that's already spelled out in the docs for compareTo() as a requirement, so I'm not sure why he's mentioning it again, and why he's saying it's "generally a good idea." I think he might be talking about consistency with the equals() method. That is, your compareTo()'s definition of equality should match that of your class's equals() method. So if myObject1.compareTo(myObject2) returns zero, then myObject1.equals(myObject2) should return true, and vice versa.
dennis deems
Ranch Hand

Joined: Mar 12, 2011
Posts: 808
.
Ken Austin
Ranch Hand

Joined: Aug 20, 2012
Posts: 39

Oh, okay. It makes sense now, guys. Thanks for clearing that up for me.

I was trying to figure out what sort of property a class could have that would allow it to be analogous. Which was making my head explode.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Ken Austin wrote:I was trying to figure out what sort of property a class could have that would allow it to be analogous.


"I'm sorry, Ken, but I'm going to have to deduct 5 points. You class isn't analagous."

Greg Charles
Sheriff

Joined: Oct 01, 2001
Posts: 2853
    
  11

Jeff Verdegan wrote:On the surface, it sounds like he's saying that, just like String, when you write your compareTo() for your own class, it should only return zero of the two objects being compared are equal. But that's already spelled out in the docs for compareTo() as a requirement, so I'm not sure why he's mentioning it again, and why he's saying it's "generally a good idea."


What docs? The JavaDoc APIs say it's a recommended, but not required:


It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."


Personally, I'm totally on board with, "If two comparable objects are equal, then o1.compareTo(o2) should return 0". If that's not the case, you could easily run into trouble. I'm more meh about the "only if" part. Maybe you have two Persons with the same name, and simply don't care which one sorts first in a list. Sloppy, maybe, but surely not as evil as having two equal objects with non-zero compare-to value.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Greg Charles wrote:
Jeff Verdegan wrote:On the surface, it sounds like he's saying that, just like String, when you write your compareTo() for your own class, it should only return zero of the two objects being compared are equal. But that's already spelled out in the docs for compareTo() as a requirement, so I'm not sure why he's mentioning it again, and why he's saying it's "generally a good idea."


What docs? The JavaDoc APIs say it's a recommended, but not required:


It's required that compareTo() returns 0 if the objects are equal according to the semantics of the ordering implemented by compareTo(). That's its documented behavior. Sorry if I wasn't clear about it.

The part that's only recommended, not required, and that I think is what the author was getting at, is that compareTo() be consistent with equals(), so that compareTo() returns zero if and only if equals() returns true.

So there are two different notions of equality, and it's recommended that they be consistent with each other.

I would also strongly recommend that compareTo() be consistent with equals(), since they both deal with the inherent semantics of equality of objects of that class. I give more leeway to Comparator, since that's external to the class, and is used for other than the "natural" ordering. And, if you're going to use your class in a SortedMap or SortedSet, its Comparable.compareTo() or Comparator.compare() must be consistent with equals or you won't get proper behavior on some of the methods.

Greg Charles
Sheriff

Joined: Oct 01, 2001
Posts: 2853
    
  11

Jeff Verdegan wrote:
It's required that compareTo() returns 0 if the objects are equal according to the semantics of the ordering implemented by compareTo(). That's its documented behavior. Sorry if I wasn't clear about it.


Is it? I'm still not reading it that way, but that's the way it should read, and you're reading that way, so I suspect I'm the one who's crazy.

It didn't escape my notice that you used both "its" and "it's" correctly in a single posting. That's rare to see these days in any Internet forum, so ... kudos!
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Greg Charles wrote:
Jeff Verdegan wrote:
It's required that compareTo() returns 0 if the objects are equal according to the semantics of the ordering implemented by compareTo(). That's its documented behavior. Sorry if I wasn't clear about it.


Is it? I'm still not reading it that way, but that's the way it should read, and you're reading that way, so I suspect I'm the one who's crazy.


compareTo() javadoc says: "Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object."

It didn't escape my notice that you used both "its" and "it's" correctly in a single posting. That's rare to see these days in any Internet forum, so ... kudos!



 
GeeCON Prague 2014
 
subject: Writing a compareTo() method