1

I know those interfaces use for sort objects in a Collection. But I am having doubt of the real difference of those. One fact i read is use comparable when you want to compare two objects with out the current object (this).

But my problem is even with comparator we compare same object type know.

What is really the difference here. I am confused. Suppose the following example,

class Person implements Comparable<Person> {
  private String firstName;
  private String lastName;
  private int age;

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public int compareTo(Person anotherPerson){     
    int anotherPersonAge =anotherPerson.getAge();  
    return this.age - anotherPersonAge;    
  }
}

If i use comparator i would have a class implement the comparator and instead of this.age, it has person.age. So what is so different here?

public class LastNameComparator implements Comparator<Person> {
  public int compare(Person person, Person anotherPerson) {
    int age1 = person.getAge();
    int age2 = anotherPerson.getAge();

     return age1 - age2; 
  }
}

I dont know the internal logic Collections.sort use. Please justify the above point if so with regard to that.

Also i believe no need to return -1,1 or 0 right. Above implementation is also valid right? One problem i am having is if we return 1 how can the list order the item according to ascending or descending order? I thought its the difference take into consider and order them according to the difference.

FrankD
  • 859
  • 4
  • 19
  • 31
  • 1
    http://stackoverflow.com/questions/1440134/java-what-is-the-difference-between-implementing-comparable-and-comparator?rq=1 – assylias Dec 04 '12 at 16:43
  • 1
    `Comparable` and `Comparator` are both generic interfaces, but you've omitted the type parameters. Why? – Matt Ball Dec 04 '12 at 16:44
  • ok i change the code to accept generics. So that i can eliminate the class type check also right. – FrankD Dec 04 '12 at 16:48
  • 1
    `Comparator` would be useful if, say, a class you're using is not open to modification and a) does not implement `Comparable` or b) its definition of 'natural ordering' is not satisfactory for your application. Generally speaking, when defining a new class that has a notion of ordering, you should implement `Comparable` for that ordering, and then use a `Comparator` for any 'unnatural' orderings. – jpm Dec 04 '12 at 16:49
  • Don't know internal logic of `Collections.sort()`? Why not read the source? http://www.docjar.com/html/api/java/util/Collections.java.html#151 – Matt Ball Dec 04 '12 at 16:50

5 Answers5

1

Consider the documentation for both Comparable

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method.

and Comparator

A comparison function, which imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort or Arrays.sort) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don't have a natural ordering.

A Comparable object can determine its order by comparing itself with another object (natural ordering), while a Comparator is an object that knows how to compare two objects and determine their particular order. The difference here is who is responsible for the comparation.

Natural ordering imposes a defined order with compareTo but what if you wanted to change that order or, even worse, there is no defined comparation logic? Here is where Comparator comes in handy, since you can sort a collection based on different comparations that can be switched dynamically by issuing a new Comparator, instead of some nasty logic where you should tell the Comparable object "Hey, now you order according to name instead of age".

Regarding the differences between the results of a comparation, they are checked for each object. For example, take three persons with age 10, 15 and 20. 15 returns 1 when compared with 10 but returns -1 when compared with 20, defining the order of the three persons.

Choose the approach that fits your needs. If your comparation logic is stable and won't be changed in the future, you might want to have Comparable objects, but should you need to sort a collection based on different criteria you should go for Comparators.

Fritz
  • 9,987
  • 4
  • 30
  • 49
0

A quick scan of the java.util.Collections javadocs provides this:

public static void sort(List list) - Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

public static void sort(List list, Comparator c) - Sorts the specified list according to the order induced by the specified comparator. All elements in the list must be mutually comparable using the specified comparator (that is, c.compare(e1, e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

It can be inferred that sort(List list) then uses the Comparable interface and sort(List list, Comparator c) uses a comparator.

To answer your final question, there is no difference between using the two methods in the way that you describe... the purpose of having the two methods is so you can compare objects in different ways, not in the same way using different implementations.

LJ2
  • 593
  • 5
  • 11
0

Consider in this way... You have Class IntegerWrapper which has one integer, and you implemented Comparable in the class. So when sorting these using Collection.sort... It will give you objects in ascending order...

But when you want to change this order and wants descending order, then you must implement comparator to sort them in desired order...

Vishal
  • 3,189
  • 1
  • 15
  • 18
0

In Java, a type can always only ever implement an interface once, that is you can't say

public class Foo implements Comparable<Foo>, Comparable<String> {}

This means the instances of Foo will always sort in a certain way - you can't have the sorting behave one way in a certain context and differently in another context.

The Comparator, on the other hand, is independent of the instances it can sort. You can have as many Comparators for a single type (as opposed to exactly one Comparable). If you need a certain sorting, just create a new Comparator and you're done.

It's also easy to write a Comparator that sorts instances of different types - this is hard to do with Comparable because all involved instances would have to know about each other: Any instance could get any other instance as argument in compareTo() and they would have to implement some common interface, etc.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
0

I'm always frighted when some uses the Comparable interface because it is nearly always the wrong choice. Comparable is used to define a natural order and not for sorting. Java knows the equals-hashcode contract that must be fulfilled. The most developers know it. But there is an additional important contract: The equals-comparable contract.

That means:

a.equals(b) <==> a.compareTo(b) == 0

In your example you cannot have two different persons with the same age in one TreeSet.