• Post Reply Bookmark Topic Watch Topic
  • New Topic

Implementing Comparator  RSS feed

 
Paul Mrozik
Ranch Hand
Posts: 117
Chrome Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I needed to implement the Comparator interface for a certain class and I came across a design problem.

Let's say I have a class like this:



Now, if I were to implement the Comparator interface here, when sorting I'd need to do this:



So here's what I did and I just want to know whether from a design perspective it makes sense:




How would you do it?



 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Mrozik wrote:Now, if I were to implement the Comparator interface here, when sorting I'd need to do this:

What makes you think that? That code won't even compile, unless MyClass implements Comparator, which seems like a very odd thing to do.

A Comparator compares two possibly non-Comparable objects of the same type; that's all it does. You don't need to set up a new one for each comparison; and you definitely don't need to incorporate it into the class you're comparing (although there's nothing illegal about it). Indeed, it's often used to provide an alternate way of comparing.

[Edit]
The only thing I would say is that Comparators should always have a type, viz:

public class MyClassComparator implements Comparator<MyClass> { ...

Winston
 
Piet Souris
Master Rancher
Posts: 2044
75
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Paul,

since it is your objective to compare MyClass objects, my first suggestion would be to put in the method

That would also mean to change the MyClass definition to

If this natural comparison doesn't meet some sorting requirements, then indeed, you can define a Comparator class,
in the way you did. But then your call

should be something like

You dont need to define a Comparator in the same class, though.

And you could also have a look at the JFC (see the Java tutorials for the Java Framework Collection),
because I think that would give you some benefits.

Greetings,
Piet
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:But then your call...should be something like

Actually, it should be:

Collections.sort(myClassList, new MyClass.MyComparator());

which is very different.

But the rest of your post is great.

Winston
 
Paul Mrozik
Ranch Hand
Posts: 117
Chrome Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your input. I implemented compareTo() in the class itself so it looks like this:



I have to admit that it was my first idea, but my code did not compile because I was implementing Comparable, not Comparable<MyClass>. Still a bit flaky with generics.

 
Piet Souris
Master Rancher
Posts: 2044
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Winston
Thanks for the correction. It shows how much I use constructions like tihs ;)

Question:
Paul wrote:
(...) but my code did not compile because I was implementing Comparable, not Comparable<MyClass>.


Now I always thought that it is strongly advised to use <Type>, but this is not mandatory, is it?

 
Paul Mrozik
Ranch Hand
Posts: 117
Chrome Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:@Winston
Thanks for the correction. It shows how much I use constructions like tihs ;)

Question:
Paul wrote:
(...) but my code did not compile because I was implementing Comparable, not Comparable<MyClass>.


Now I always thought that it is strongly advised to use <Type>, but this is not mandatory, is it?



Well, I initialized the list as:



and I got a compiler error when attempting to use Collections.sort(myList);

Had I just initialized it as:

List myList = new ArrayList();

I suppose the implementation of compareTo() would be as such:



and then I'd need to cast to Type.



 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you show the code that wasn't compiling, because Collections.sort() should work the way you described it.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Mrozik wrote:Well, I initialized the list as:and I got a compiler error when attempting to use Collections.sort(myList);

Sorry if it sounds condescending, but I just want to eliminate the bleedin' obvious:
You do realize that 'Type' is just any type?

The assignment should be (working from above):
List<MyClass> myList = new ArrayList<myClass>();

Winston
 
Paul Mrozik
Ranch Hand
Posts: 117
Chrome Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, I'll show you what I did:



I used Person as the parameter type for compareTo() but did not use implement Comparable<Person>.


Winston, yes I realize that Type is just any type.

 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul, take a look at this code and see what you can take from it. If you have questions, feel free to ask.
 
Paul Mrozik
Ranch Hand
Posts: 117
Chrome Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


Thanks Stephan.

So this is how I understand it:

1. Initially last names are compared
2. If they're the same, first names are compared
3. If those are the same, objects are compared by hash codes

I would have never thought about comparing hash codes, but it makes perfect sense. I have a unique ID for every person in my class so I suppose that could also be used instead of the hash code.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Mrozik wrote:
I would have never thought about comparing hash codes, but it makes perfect sense. I have a unique ID for every person in my class so I suppose that could also be used instead of the hash code.


I would tend to avoid using hashCode. On different runs of your app, or under different versions of the JVM, or even copying those objects during a single run on one JVM, the otherwise-equal objects' identity hashCodes might come out in a different order. If the order matters, pick a field that has some semantic meaning to those objects (such as the ID field you mention). And if the order doesn't matter, then why bother adding the extra comparison, instead of just letting them stay in whatever order they happen to be in already?

Also, be aware that that example is subject to NPE if you don't have a precondition that lastName and firstName must always be non-null. If you do accept null values for those fields, then you'll have to test for it before calling their compareTo methods, and just return -1 or +1 if one is null and not the other, depending of course on whether you want nulls to appear at the beginning of the sorted result or the end.
 
Stephan van Hulst
Saloon Keeper
Posts: 7992
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I added the identityHashCode to make the class more consistent with equals. Two distinct person objects are never equal, so two distinct person objects should probably also compare differently. Using your own ID is even better than using identityHashCode.
 
Sivakumar P Annamalai
Greenhorn
Posts: 2
Eclipse IDE Hibernate Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I added the identityHashCode to make the class more consistent with equals. Two distinct person objects are never equal, so two distinct person objects should probably also compare differently. Using your own ID is even better than using identityHashCode.


Two distinct person objects are never equal but their hash codes can be same.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!