Suppose I have a Student class with attributes name and id. And I want to sort the List of students in natural order of their respective ids using Collections.sort() method. I can do it in following two ways:

 public class Student implements Comparable<Student> {

     private Long id;
     private String name;

     // getters and setters..

     public int compareTo(Student student){
         return this.getId().compareTo(student.getId());
     }
 }

And the other way is:

public class Student implements Comparable<Long> {

    private Long id;
    private String name;

    // getters and setters..

    public int compareTo(Long id){
        return this.getId().compareTo(id);
    }
}

And then use the Collections.sort() method to sort the list of students. My question or confusion is what difference does it make if we use one over other as they both produce the same result.

2

There are 2 best solutions below

0
On BEST ANSWER

If you implement Comparable<Long>, Collections.sort() will not be able to use it on a List<Student> because Collections.sort() will have no way of figuring out where to get the Long from to pass to compareTo(Long).

0
On

Comparable's type parameter dictates by what type of objects your type is comparable with. In the former example, you're making Students comparable with each other, and in the latter example, you're making students comparable with Longs.

Generally speaking, you should use Student implements Comparable<Student>. Student implements Comparable<Long> makes little sense from an OO design point of view, since I presume you want to compare Student instances amongst each other.

EDIT: As Jason points out in another answer, Student implements Comparable<Long> is also unusable with Collections.sort(), unless Student extended Long somehow. And that's not possible because Long is final.

Also, using Student implements Comparable<Student> allows you to encapsulate the exact comparison being done. If later on, you decide to change the internal representation of id, or decide that you want to use a different field, or implement secondary comparisons using multiple fields, and so on, then existing users of your Student type won't break even if you change the compareTo(Student student) implementation.

For the above reasons you will rarely see types "in the wild" where SomeType implements Comparable<SomeOtherType>. SomeType will most likely be comparable with other instances of SomeType (i.e. SomeType implements Comparable<SomeType>).