Search code examples
javasortingcollectionsgeneric-collections

Confusion about Collections.sort(List<T> list, Comparator<? super T> c) example


Here is the code

   import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class Dog implements Comparator<Dog>, Comparable<Dog> {
    private String name;
    private int age;

    Dog() {
    }

    Dog(String n, int a) {
        name = n;
        age = a;
    }

    public String getDogName() {
        return name;
    }

    public int getDogAge() {
        return age;
    }

    // Overriding the compareTo method
    public int compareTo(Dog d) {
        return (this.name).compareTo(d.name);
    }

    // Overriding the compare method to sort the age
    public int compare(Dog d, Dog d1) {
        return d.age - d1.age;
    }
}

public class Main {

    public static void main(String args[]) {
        // Takes a list o Dog objects
        List<Dog> list = new ArrayList<Dog>();

        list.add(new Dog("Shaggy", 3));
        list.add(new Dog("Lacy", 2));
        list.add(new Dog("Roger", 10));
        list.add(new Dog("Tommy", 4));
        list.add(new Dog("Tammy", 1));
        Collections.sort(list);// Sorts the array list

        for (Dog a : list)
            // printing the sorted list of names
            System.out.print(a.getDogName() + ", ");

        // Sorts the array list using comparator
        Collections.sort(list, new Dog());
        System.out.println(" ");
        for (Dog a : list)
            // printing the sorted list of ages
            System.out.print(a.getDogName() + "  : " + a.getDogAge() + ", ");
    }
}

I know that the 2-argument sort method here takes the arguments of type List and a Comparator. But here when we pass the list Dog and a new Object of Dog, I just don't understand what is happening in the compare() method? i.e.

return d1.age - d2.age;

What does this signify? And if I do

return d1.age + d2.age; 

why does it change the ordering?


Solution

  • for d1.age - d2.age

    • if negative number, then d1 is logically less than d2 in sort order
    • if positive, then d1 is logically greather than d2 in sort order
    • if 0, then objects are equal

    You can refer the javadoc for compare method

    So when you are sorting dogs, and your compare method is comparing their ages, hence Tammy is less than Lacy according to the your method implementation.

    Making Dog implement both Comparable and Comparator seems like a bad idea to me.

    • Collections.sort(list) will cause compareTo() method to be invoked
    • Collections.sort(list, new Dog()) will cause compare() method to be invoked

    I believe you should look into sorting user defined object using Comparable and Comparator