How to use Comparator in Java to sort How to use Comparator in Java to sort java java

How to use Comparator in Java to sort


There are a couple of awkward things with your example class:

  • it's called People while it has a price and info (more something for objects, not people);
  • when naming a class as a plural of something, it suggests it is an abstraction of more than one thing.

Anyway, here's a demo of how to use a Comparator<T>:

public class ComparatorDemo {    public static void main(String[] args) {        List<Person> people = Arrays.asList(                new Person("Joe", 24),                new Person("Pete", 18),                new Person("Chris", 21)        );        Collections.sort(people, new LexicographicComparator());        System.out.println(people);        Collections.sort(people, new AgeComparator());        System.out.println(people);    }}class LexicographicComparator implements Comparator<Person> {    @Override    public int compare(Person a, Person b) {        return a.name.compareToIgnoreCase(b.name);    }}class AgeComparator implements Comparator<Person> {    @Override    public int compare(Person a, Person b) {        return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;    }}class Person {    String name;    int age;    Person(String n, int a) {        name = n;        age = a;    }    @Override    public String toString() {        return String.format("{name=%s, age=%d}", name, age);    }}

EDIT

And an equivalent Java 8 demo would look like this:

public class ComparatorDemo {    public static void main(String[] args) {        List<Person> people = Arrays.asList(                new Person("Joe", 24),                new Person("Pete", 18),                new Person("Chris", 21)        );        Collections.sort(people, (a, b) -> a.name.compareToIgnoreCase(b.name));        System.out.println(people);        Collections.sort(people, (a, b) -> a.age < b.age ? -1 : a.age == b.age ? 0 : 1);        System.out.println(people);    }}


Here's a super short template to do the sorting right away :

Collections.sort(people,new Comparator<Person>(){   @Override   public int compare(final Person lhs,Person rhs) {     //TODO return 1 if rhs should be before lhs      //     return -1 if lhs should be before rhs     //     return 0 otherwise (meaning the order stays the same)     } });

if it's hard to remember, try to just remember that it's similar (in terms of the sign of the number) to:

 lhs-rhs 

That's in case you want to sort in ascending order : from smallest number to largest number.


Use People implements Comparable<People> instead; this defines the natural ordering for People.

A Comparator<People> can also be defined in addition, but People implements Comparator<People> is not the right way of doing things.

The two overloads for Collections.sort are different:

  • <T extends Comparable<? super T>> void sort(List<T> list)
    • Sorts Comparable objects using their natural ordering
  • <T> void sort(List<T> list, Comparator<? super T> c)
    • Sorts whatever using a compatible Comparator

You're confusing the two by trying to sort a Comparator (which is again why it doesn't make sense that Person implements Comparator<Person>). Again, to use Collections.sort, you need one of these to be true:

  • The type must be Comparable (use the 1-arg sort)
  • A Comparator for the type must be provided (use the 2-args sort)

Related questions


Also, do not use raw types in new code. Raw types are unsafe, and it's provided only for compatibility.

That is, instead of this:

ArrayList peps = new ArrayList(); // BAD!!! No generic safety!

you should've used the typesafe generic declaration like this:

List<People> peps = new ArrayList<People>(); // GOOD!!!

You will then find that your code doesn't even compile!! That would be a good thing, because there IS something wrong with the code (Person does not implements Comparable<Person>), but because you used raw type, the compiler didn't check for this, and instead you get a ClassCastException at run-time!!!

This should convince you to always use typesafe generic types in new code. Always.

See also