• Post Reply Bookmark Topic Watch Topic
  • New Topic

Relationship of Comparable and Comparator interfaces in Java.  RSS feed

 
kiran madhan
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I faced this question in some interview....I tried to explain it...but in vain....!
The interviewer asked me to explain the relationship among Comparable and Comparator...with an example...!

May I get a real-time or real-world example to it...!
 
Puspender Tanwar
Ranch Hand
Posts: 471
2
Java
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Kiran,
Comparable<T> interface is in java.lang pack while Comparator<T> is in java.util package.
Comparable has only one method compareTo();
Comparator has only one method compare();
Suppose we are having a Student class, in which we are having rollNo, age, name as its field. Now, understand where to use Comparable and where to use Comparator. Suppose you are having a collection of Students stored in ArrayList<Student>, which is not arranged in a proper manner. Now, you just want to arrange(sort) this ArrayList by using the Collection.sort() method.  If your Student are having nature of Comparable i.e Students implements Comparable, than Student can only be sorted either on rollNo or age or name. You cannot sort based on all fields.
But, you your students are having a Comparator nature, then they can be sorted on rollNo, name, age (on all field).

Now lets understand it practically. Here is our Student class

here is our test class which uses Student and prints sorted collection

output :
[rollNo: 2  Age: 18  Name: puspen
, rollNo: 10  Age: 15  Name: ajay
, rollNo: 5  Age: 20  Name: deepak
, rollNo: 4  Age: 22  Name: sharma
]
[rollNo: 2  Age: 18  Name: puspen
, rollNo: 4  Age: 22  Name: sharma
, rollNo: 5  Age: 20  Name: deepak
, rollNo: 10  Age: 15  Name: ajay
]
i think you can see the increasing order of rollNo

But, what if you want to sort on age or want to sort on name ? You would have to go to the Student class and change the comareTo() method ? But what if again sorting on basis of rollNo is needed ? Again changing the code. This could be very painful. So the solution to this is use Comparator interface. Here it is how :

sorted output is : based on unsorted, age, rollNo, name respectively :
[rollNo: 2  Age: 18  Name: puspen
, rollNo: 10  Age: 15  Name: ajay
, rollNo: 5  Age: 20  Name: deepak
, rollNo: 4  Age: 22  Name: sharma
]
[rollNo: 10  Age: 15  Name: ajay
, rollNo: 2  Age: 18  Name: puspen
, rollNo: 5  Age: 20  Name: deepak
, rollNo: 4  Age: 22  Name: sharma
]
[rollNo: 2  Age: 18  Name: puspen
, rollNo: 4  Age: 22  Name: sharma
, rollNo: 5  Age: 20  Name: deepak
, rollNo: 10  Age: 15  Name: ajay
]
[rollNo: 10  Age: 15  Name: ajay
, rollNo: 5  Age: 20  Name: deepak
, rollNo: 2  Age: 18  Name: puspen
, rollNo: 4  Age: 22  Name: sharma
]


you may have doubt here :

s1 and s2 represent the current and next element in the List. s1 is the current element and s2 is the element next to s2. this is used for comparing the adjacent elements.

Hope it helps

 
Campbell Ritchie
Marshal
Posts: 55793
164
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When it comes to interview questions, there are two things to consider:-
  • 1: What you answered
  • 2: How you said it
  • Please tell us how you answered the question.

    Have you been through the Java™ Tutorials about the Collections Framework? Inside the section about interfaces, there is a page called object ordering. That is a really good explanation of ordering. That will doubtless explain the different between the two. If you go through the String class documentation, you will find both Comparable and a Comparator.
     
    Campbell Ritchie
    Marshal
    Posts: 55793
    164
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Puspender Tanwar wrote:. . .
    s1 and s2 represent the current and next element in the List. s1 is the current element and s2 is the element next to s2. this is used for comparing the adjacent elements.

    Hope it helps

    Nice explanation, but at the end, s1 and s2 represent the two arguments passed to that method. It doesn't matter where they come from; remember methods don't record the source of their arguments. If you use Collections#sort() or Arrays#sort(), you do not know the order that pairs are compared in; the algorithm used varies depending on the type of array.
    Please explain why the minus sign is error‑prone, Have you worked out how to create a Comparator from a λ?
     
    Liutauras Vilda
    Marshal
    Posts: 4670
    320
    BSD
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:Please explain why the minus sign is error‑prone
    Very good observation.

    Anyway, Puspender Tanwar, have a cow for great post. It seems you're going to be busy now with cattle breeding
     
    kiran madhan
    Ranch Hand
    Posts: 34
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:When it comes to interview questions . . .


    what i told is "comparable helps us to compare objects based on the comparator defined by comparator."
     
    kiran madhan
    Ranch Hand
    Posts: 34
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    kiran madhan wrote:. . . what i told is "comparable helps us to compare objects based on the comparator defined by comparator."


    but now i came to know that what ever i told is absolutely wrong.
     
    kiran madhan
    Ranch Hand
    Posts: 34
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:. . . Have you worked out how to create a Comparator from a λ?



    we have two methods in Comparator<T> interface....which method to be used at what situation....how can i know that....!
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7821
    142
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you are referring to the two comparing() methods, you can use either to create a Comparator that will compare objects based on some property of the objects. The method that only accepts one argument requires that these properties are naturally comparable to each other. The method that accepts two arguments allows you to provide another Comparator to compare the properties with.
     
    Puspender Tanwar
    Ranch Hand
    Posts: 471
    2
    Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:Nice explanation.........Please explain why the minus sign is error‑prone, Have you worked out how to create a Comparator from a λ?

    Thanks Campbell . I was also thinking that using the argument depends on the algo which is being used, but was not sure. Thanks for making me sure
    The reason I  think of for error prone could be, suppose we want to sort on price basis, where price is any double value. In that case it would not work as expected. This is the only reason which came to my mind. Could you please explain any other reason ?
    The second thing you asked, I didn't understand, please elaborate that also.

    Liutauras Vilda wrote:Anyway, Puspender Tanwar, have a cow for great post. It seems you're going to be busy now with cattle breeding

    Thanks a lot Vilda, It feels amazing on getting the first cow. I was waiting for this from the first answer I gave on coderanch.

     
    Tobias Bachert
    Ranch Hand
    Posts: 85
    18
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I assume Campbell meant problems regarding over-/underflow with the minus sign (it should be "return a < b ? -1 : a == b ? 0 : 1;" (or direct Integer.compare(int,int)int) instead of "return a - b;").
    Regarding his seconds statement: With Java8 and lambda (λ)-expressions it is possible to achieve the same with way less typing (the Comparator-implementing classes can be replaced with Comparator.comparing(...) and Comparator.comparingInt(...)).
     
    Liutauras Vilda
    Marshal
    Posts: 4670
    320
    BSD
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    How about negative values? -4 - -5
     
    praveen kumaar
    Ranch Hand
    Posts: 461
    22
    Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Puspender Tanwar wrote:Thanks Campbell . I was also thinking that using the argument depends on the algo which is being used, but was not sure. Thanks for making me sure
    The reason I  think of for error prone could be, suppose we want to sort on price basis, where price is any double value. In that case it would not work as expected. This is the only reason which came to my mind. Could you please explain any other reason ?


    reason is what if one of the argument is a "negative" value in that case you will get wrong result and also may be overflow occurs because difference can go beyond the integer maximum value - ( 2^31-1).

    ( 2^31-1 )-( -2^31 )--->overflow.
    or
    -2^31-( 2^31-1 )---->again overflow.
     
    praveen kumaar
    Ranch Hand
    Posts: 461
    22
    Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Anyway! congrats for your first cow puspen
     
    Piet Souris
    Rancher
    Posts: 1984
    67
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Puspender Tanwar wrote:(...)If your Student are having nature of Comparable i.e Students implements Comparable, than Student can only be sorted either on rollNo or age or name. You cannot sort based on all fields.

    hi Puspender,

    I'm not sure I uderstand this correctly. Can you elaborate a little?
     
    Piet Souris
    Rancher
    Posts: 1984
    67
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Liutauras Vilda wrote:How about negative values? -4 - -5

    ? Gives 1, as it should (but to whom was this question aimed?)
     
    Liutauras Vilda
    Marshal
    Posts: 4670
    320
    BSD
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Piet Souris wrote:
    Liutauras Vilda wrote:How about negative values? -4 - -5

    ? Gives 1, as it should (but to whom was this question aimed?)
    Agh, my bad, right, +1 it is what we expect. -4 - 5 that should mess up things.
     
    Puspender Tanwar
    Ranch Hand
    Posts: 471
    2
    Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    praveen kumaar wrote:reason is what if one of the argument is a "negative" value in that case you will get wrong result and also may be overflow occurs because difference can go beyond the integer maximum value - ( 2^31-1).
    ( 2^31-1 )-( -2^31 )--->overflow.
    or
    -2^31-( 2^31-1 )---->again overflow.
    Anyway! congrats for your first cow puspen

    Thank you praveen
    yup, these could also be the reasons.

    oh, in the second line of campbell post, he was talking about lambdas ? Actually I have not read it yet, but Know it will reduce the code to much extent.
     
    Puspender Tanwar
    Ranch Hand
    Posts: 471
    2
    Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Piet Souris wrote:
    Puspender Tanwar wrote:(...)If your Student are having nature of Comparable i.e Students implements Comparable, than Student can only be sorted either on rollNo or age or name. You cannot sort based on all fields.

    hi Puspender,

    I'm not sure I uderstand this correctly. Can you elaborate a little?

    sure Piet. IF Student class implements Comparable interface, then we have only one filed on which we can sort our List at a time. Since, only one compareTo() method we have and that can sort only on the basis of single field, either on basis of roLLno, or on age or on name (not all). Unlike Comparator, we cannot have specific class and respective methods for sorting List of Student data on the basis of Student's fields.

    Hope it is clear now
     
    Piet Souris
    Rancher
    Posts: 1984
    67
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yes, thank you for this very quick elaboration, good for your second cow!

    But, in your first reply, in the compareTo method: if both Students have the same rollno, can't you next compareTo the names or so?
     
    Campbell Ritchie
    Marshal
    Posts: 55793
    164
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    kiran madhan wrote:. . . we have two methods in Comparator<T> interface.... . . .
    We all know that after 55BC,
    Sellars and Yeatman, 1066 and All That, chapter 1 wrote:[Julius Caesar was] compelled to invade Britain again the following year (54 BC, not 56, owing to the peculiar Roman method of counting).
    Well, this is the peculiar Java® method of counting. Start by getting a Java7 version of Comparator and you can see clearly that it has one two methods. But in Java8, it is clearly marked as a FunctionalInterface, and a Functional Interface has only one method. You need to read carefully. Look at the Java7 version and it tells you that you can get away without implementing the equals method. In fact, I can't remember ever seeing a Comparator instance which did override equals. Now look at the Java® Language Specification (=JLS) or the functional interface link I gave earlier, and you see it is only abstract methods which are counted. If you go through Comparator in Java7, it tells you there is no need to implement equals, so equals is not an abstract method. In fact, equals is inherited from the Object class, and there is only one method which really must be implemented, viz. compare().

    That means you can use a λ to create a Comparator:-Don't quote the whole of a preceding post, which simply makes the thread longer and longer without adding information. I have deleted most of the quotes.
     
    Campbell Ritchie
    Marshal
    Posts: 55793
    164
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Liutauras Vilda wrote:. . . -4 - 5 that should mess up things.
    Why? I can't see anything wrong with that formula. It will return something negative to show that −4 < 5.
     
    Campbell Ritchie
    Marshal
    Posts: 55793
    164
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Puspender Tanwar wrote:. . . IF Student class implements Comparable interface, then we have only one filed on which we can sort our List at a time. . . .
    As PS has hinted, that bit about only one field is incorrect.
     
    Liutauras Vilda
    Marshal
    Posts: 4670
    320
    BSD
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell Ritchie wrote:
    Liutauras Vilda wrote:. . . -4 - 5 that should mess up things.
    Why? I can't see anything wrong with that formula. It will return something negative to show that −4 < 5.
    I might take some rest today, it's been hard day for me, I totally wrote nonsense in my 2 latest posts.

    Negative 1st is smaller, positive 1st is bigger.. Confusing those.
     
    Campbell Ritchie
    Marshal
    Posts: 55793
    164
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Liutauras Vilda wrote:. . . I might take some rest today, . . .
    Taking some beer will probably do you even more good.

    But actually, many a true word [is] spoken in jest. Tiredness is dangerous in programming, and it is beneficial to take time off.
     
    Puspender Tanwar
    Ranch Hand
    Posts: 471
    2
    Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Piet Souris wrote:Yes, thank you for this very quick elaboration, good for your second cow!
    But, in your first reply, in the compareTo method: if both Students have the same rollno, can't you next compareTo the names or so?

    Wow, another cow
    Unfortunately NO., we cannot compareTo the name if rollNo are same.
    However we can, if we could have knew which sorting algo collections.sort() method is using. For bubble sort, i have written some code, may or may not it can be correct . For now, it is not working as per expectation:

    the updated main method:
     
    Puspender Tanwar
    Ranch Hand
    Posts: 471
    2
    Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Forgot to Thank you.
    Thanks a lot Piet Souris for the cow Breeding started ;)
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7821
    142
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Don't do this. The compareTo() method should always return the same result if the input is the same. It should also have no side effects.

    If the compareTo() method should only return 0 when the objects being compared are actually the same instance, you should include some 'identity' field. If rollNo fulfills that requirement, then your class should override equals() and hashCode() to ensure that the compareTo() method is consistent-with-equals. In the following example I'll just call the field id:
     
    Shekhar Ray
    Greenhorn
    Posts: 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Comparable interface is used when sorting order can be added inside the same class and the objects can be sorted according to natural order of fields.

    Comparable interface is used when sorting information isn’t available inside the object itself or a custom sorting logic needs to be implemented.

    Although you don't need to, but a class can implement both Comparable and Comparator interface. In such scenario, the Comparator takes precedence over Comparable.

    Reference:
    TopJavaTutorial
     
    Campbell Ritchie
    Marshal
    Posts: 55793
    164
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Shekhar Ray wrote:. . . In such scenario, the Comparator takes precedence over Comparable.

    Reference:
    TopJavaTutorial
    Welcome to the Ranch

    The tutorial you quoted has confused you, and I don't think well of it. That does not mean there is any “precedence” between a Comparator and Comparable; it means that is an example where the user has instructed the TreeSet object to use a Comparator. It is clearly shown in the TreeSet documentation:-
    The elements are ordered using their natural ordering, or by a Comparator provided at set creation time, depending on which constructor is used.
    I also think you are mistaken about sorting information not available in the object. If you are sorting objects, you must sort them on information inside the object. If you read the Java™ Tutorials section (I am 99% sure I have already posted that link elsewhere), you will find out about sorting. Some objects have a natural ordering; if you are given the Integers 5, 4, 3, 1, 2, it will be pretty obvious to everybody that they order as 1, 2, 3, 4, 5.
    If however you are given the names Shekhar Ray, praveen kumaar and Campbell Ritchie, how are you going to order them? You might order them praveen kumaar, Shekhar Ray, Campbell Ritchie or
    Campbell Ritchie, praveen kumaar, Shekhar Ray. You can create different Comparators<Name> to implement the two different orders.
     
    kiran madhan
    Ranch Hand
    Posts: 34
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    here, all of you great programmers are giving broader answers...! But give a simple answer please....as per the question...!
    I am so much confused about all these answers...!
    my question is when to use Comparable and what are the problems are ....and when to use Comparator.?
    thanks in advance to all...of you..?
     
    Paul Clapham
    Sheriff
    Posts: 22527
    43
    Eclipse IDE Firefox Browser MySQL Database
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    kiran madhan wrote:my question is when to use Comparable and what are the problems are ....and when to use Comparator.?


    Shekhar Ray wrote:Comparable interface is used when sorting order can be added inside the same class and the objects can be sorted according to natural order of fields.

    Comparable interface is used when sorting information isn’t available inside the object itself or a custom sorting logic needs to be implemented.
     
    Dave Tolls
    Rancher
    Posts: 2914
    36
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Of course that second sentence has a typo and should read:

    "Comparator interface is used when sorting information isn’t available inside the object itself or a custom sorting logic needs to be implemented."
     
    Frits Walraven
    Creator of Enthuware JWS+ V6
    Saloon Keeper
    Posts: 2988
    223
    Android Chrome Eclipse IDE
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Congratulations Kiran Madhan !!

    This question has been selected for the September Journal

    Cow!
     
    kiran madhan
    Ranch Hand
    Posts: 34
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Wow...! Thanks a lot Frits Walraven...!
    I am so happy..and Thanks for 1ST COW....COW..!
     
    Campbell Ritchie
    Marshal
    Posts: 55793
    164
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Congratulations on the cow, for asking a question interesting enough for the journal.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!