Comparator interface – how to sort it all (out)?

Hi!

In this post I would like to show you a simple way for sorting list of objects in the specified order using Comparator interface.

Sorting ArrayList of Integers

Sorting ArrayLists is quick and easy, as long as they store only numbers. Let us have some ArrayList of Integers:

ArrayList arrayListOfNumbers = new ArrayList<>();
for(int i=0; i<10;i++)
{
arrayListOfNumbers.add(new Random().nextInt(100));
}

with some random numbers:
[74, 71, 79, 14, 94, 95, 21, 87, 83, 0]

To sort it, we only need to use sort method:

 Collections.sort(arrayListOfNumbers);

And then we have our numbers sorted in ascending order:
[0, 14, 21, 71, 74, 79, 83, 87, 94, 95]

Then we can use reverse:

 Collections.reverse(arrayListOfNumbers);

to have them sorted in descending order:
[95, 94, 87, 83, 79, 74, 71, 21, 14, 0]

You can use Collections.sort() and reverse() to manage ArrayList of String as well.

Sorting ArrayList of Objects

But we don’t use ArrayList only for storing numbers or text, right? We usually use them to store our objects. How to handle sorting then?

Suppose we have an ArrayList containing actresses:

ArrayList arrayListOfActress = new ArrayList<>();


public class Actress {

 private String name; 
 private String surname; 

 public Actress(String name, String surname) 
 { this.name = name; this.surname = surname; } 

 public String getFirstName() { return name; } 
 public void setFirstName(String firstName) { this.name = firstName; } 
 public String getSurname() { return surname; } 
 public void setSurname(String surname) { this.surname = surname; } 

 @Override public String toString() { return name + " " + surname; }

}

that after adding some actresses looks like this:

ArrayList with some actresses: 
[Julia Roberts, Amy Adams, Meryl Streep, Nicole Kidman, Emma Stone, Jennifer Aniston]

When we try to use Collections.sort() operation, compilator would throw an error:

The method sort(List) in the type Collections is not applicable for the arguments (ArrayList)

What happened here?

Collections.sort() had no problems with lists containing numbers or texts. So why does not work for list of Actress?

The reason for this, is that Actress object is not built-in Java class like Integer or String, so compilator doesn’t know how to compare them. What does it mean to have Actress objects sorted anyway? Should they be sorted in alphabetical order by name or surname? Which class fields should be taken into account?

Collections.sort() worked for numbers and texts, because both Integer and String implement Comparable interface. Implementation of Comparable provides natural ordering for sorting, which is signed numerical for Integer and lexicographic for String. In case of Actress objects we need to specify the exact way how they should be compared. We can achieve this by implementing Comparator interface.

Interface Comparator

Comparator interface has only one method:

public interface Comparator {
   int compare(T o1, T o2);
}

Its return value provides the result of comparing two objects o1 and o2:

Zero            when o1 == o2
Positive number when o1 >  o2
Negative number when o1 <  o2

Below you can see simple ActressComparator, that sorts actresses in alphabetical order by their surnames:

import java.util.Comparator;

public class ActressComparator implements Comparator {

 @Override 
 public int compare(Actress a, Actress b) 
 { 
   return a.getSurname().compareToIgnoreCase(b.getSurname()); 
 }

}

We use it as the argument for sort() method:

arrayListOfActress.sort(new ActressComparator());

And in effect our list of object is sorted!

Actresses sorted by surname: 
[Amy Adams, Jennifer Aniston, Nicole Kidman, Julia Roberts, Emma Stone, Meryl Streep]

Of course it’s only a start for comparing more complex objects in a more sophisticated way than sorting actresses by their surnames 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s