Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Sort with Comparable

I have an ArrayList of Person objects. A Person has name, age and height. My goal is to sort this ArrayList<Person>. I have implemented Comparable<Person> and have defined compareTo() but when I try to sort it, it give me this error:

The method sort(Comparator) in the type ArrayList is not applicable for the argument ()"

The way I understand is that if you implement Comparable and then define compareTo everything else is magically done for you.

Can some one explain how to this works and why I am getting this error?

like image 423
user6509972 Avatar asked Mar 10 '23 09:03

user6509972


2 Answers

My guess is that your code looks like this:

ArrayList<Person> people = ...;
people.sort();

Look at the JavaDoc for ArrayList. Do you see a method public void sort() (with no parameters)? No - there is no such method.

That is the meaning of the error: The method sort(Comparator) in the type ArrayList is not applicable for the argument () -- There is a method sort(Comparator), but you have not supplied parameters that match it.

Assuming Person implements Comparable (and therefore has a compareTo() method), you can use Collections.sort(), which sorts arbitrary List<Comparable>

Collections.sort(people);

This is because Collections has a static method:

static <T extends Comparable<? super T>> void sort(List<T> list);

(it also has a sort(List<T> list, Comparator<T> comparator))

... or you can pass a comparator to List.sort(), which is quite easy with Java 8 lambdas:

people.sort((a,b) -> a.compareTo(b));

(Or, if you prefer the old style):

people.sort(new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

(Actually as of Java 8, this comparator is provided by the standard library, as Comparator.naturalOrder())

The point of comparators is that you can sort according to different criteria. For example:

people.sort((a,b) -> a.lastName().compareTo(b.lastName()));
people.sort((a,b) -> a.lastName().compareToIgnoreCase(b.lastName()));
people.sort((a,b) -> Integer.compare(a.age(),b.age()));
// etc.

... or using methods in Comparator:

people.sort(Comparator.comparing(Person::lastName));
people.sort(Comparator.comparing(Person::lastName)
        .thenComparing(Person::firstName));
like image 83
slim Avatar answered Mar 20 '23 22:03

slim


Either you use a structure which uses the Comparable interface to order its elements when you add a new element inside it :

TreeSet<Person> persons = new TreeSet<>();
Person personOne = ...
Person personTwo = ...
persons.add(personOne);
persons.add(personTwo);

Either you use a List and the Collections.sort(List<T> list) method which takes as argument the list you want to sort (there is an overload of this method but it is not relevant in your case):

List<Person> persons = new ArrayList<>();
Person personOne = ...
Person personTwo = ...
persons.add(personOne);
persons.add(personTwo);
Collections.sort(persons);

With the TreeSet, the elements are sorted as soon as added and with the List, the elements are not sorted when you add them.
Only, the call to the Collections.sort() method sorts the list.

like image 23
davidxxx Avatar answered Mar 20 '23 21:03

davidxxx