One of the most common functions we need as developers dealing with data is sorting--by being able to sort our data, we can optimize our algorithms to run much faster, and find the data it needs to in a fraction of the time that it would take to otherwise. Java Collections and Sorting methods in it - 1 As a quick thought experiment: imagine that you are searching for a name through a university’s roster. There may be tens of thousands of students at this school. If the roster you were given was not in alphabetical order, you would need to flip through every single page and look very carefully to make sure you didn’t skip a single name anywhere, until you finally find the name you are looking for. On the other hand, if the roster was alphabetized, not only do you have to be less rigorous in your search, but you could easily jump to the section in the roster with the same first letter, and continue to jump around pages in big leaps until you land upon the person you were looking for. The more data you are working with, the more important it is that you are using it as effectively and efficiently as possible. In this article, we will go over how to sort any List implementation in Java (including ArrayList) using the Collections sort method.

How to Sort an ArrayList in Java using the Java Collections.sort method

Let’s talk about Java Collections.sort method. The java.util package contains many useful utilities and packages which are often used by developers, including the ArrayList. Suppose you have the following simple program:
import java.util.*;
import java.io.*;
class Main{
     public static void main(String[] args){
          List<String> colors = new ArrayList<String>();
          colors.add("Red    ");
          colors.add("Orange");
          colors.add("Green");
          colors.add("Blue");
    }
}
You want to be able to print out the colors list, but in alphabetical order. How might you do this? Using java.util.Collections, sorting is as easy as a one-liner:
Collections.sort(colors);
Ta-da! Your colors list has now been sorted in-place. If you were to print out the list, as such:
System.out.println(colors);
Then you would get the following output:
[Blue, Green, Orange, Red]
How easy was that?! It would be just as easy to use Collections.sort() to sort into ascending order a list of Integers, Floats, or any other simple data type for that matter. But what if you wanted to sort in descending order? There are definitely cases where this makes sense--imagine that you had a list of test scores for a certain class, and you wanted to figure out who the top-scoring students are. It would make much more sense to sort the list in descending order (highest scores first), so that the answers you are looking for are right at the top. Thankfully, Collections.sort()is overwritten with an optional 2nd parameter, which allows you to do just this:
sort(List l, Comparator c)
But what’s a comparator? Well, a comparator is simply a function that compares two inputs and returns a number representing which input comes first. If you are sorting an ArrayList of primitive data types, then Java Collections already provides you with a reverseOrder() comparator. It can be called like this:
Collections.sort(colors, Collections.reverseOrder());
Now, colors have been reverse sorted in-place so that if you printed it out, you would get the following output:
[Red, Orange, Green, Blue]

How to use Collections to sort non-primitive data types in Java

So far, you’ve seen that sorting ArrayLists of strings or ints in Java using the Collections.sort() method is as easy as one line of code. But oftentimes, your ArrayLists will be storing non-primitive data types. When you are working with data that has more complex attributes, you will want to write classes to represent these objects and how they will be compared to each other using their attributes. To explore an example of this, let’s revisit the example of sorting a list of colors, but this time, instead of sorting Strings, we will be sorting Color objects. Our basic Color class might look something like this:
public class Color{
	private int r;
	private int g;
	private int b;
	private String name;

	Color(String name, int red, int green, int blue){
   	this.name = name;
    	this.r = red;
   	this.g = green;
   	this.b = blue;
	}
}
In order to make our Color class compatible with Collections.sort(), so that Collections can understand how to compare and sort Color objects, we need to make two small modifications:
  1. make Color a Comparable object (add implements Comparable<Object>)
  2. override the compareTo method in the class (override public int compareTo(Object o))
With these modifications, our class now looks like this:
public class Color implements Comparable<Object>{
	private int r;
	private int g;
	private int b;
	private String name;

	Color(int red int green, int blue, String name){
    	this.r = red;
   	this.g = green;
   	this.b = blue;
   	this.name = name;
	}

	@Override
	public int compareTo(Object o) {
    	Color c = (Color) o;
    	return this.name.compareTo(c.name);
	}
}
Notice that the Color’s compareTo method simply calls the String’s compareTo method; sorting will be done in alphabetical order. If we wanted to sort by red value in ascending order, for example, we could replace the return statement with return this.r - c.r; (if we wanted to sort by green value in descending order, it’d be return c.g - this.g;). Now, if we call
Collections.sort(colors);
on an ArrayList of Colors rather than just Strings, it would work because Collections understands how to compare Color objects. If you do not want to make your object implement Comparable<Object>, you can alternatively write a comparator for your class, and pass that into the 2-parameter Collections.sort() method. A comparator overrides a method public int compare(Object one, Object two), and the Collections.sort() method uses this to compare objects while sorting. An example of SortByName and SortByRed comparators are implemented below:
class SortByName implements Comparator<Color>
{
	public int compare(Color a, Color b)
	{
    	return a.name.compareTo(b.name);
	}
}

class SortByRGB implements Comparator<Color>
{
	public int compare(Color a, Color b)
	{
    	return a.r - b.r;
	}
}
With this, you can now call
Collections.sort(colors, new SortByName());
without the Color class actually implementing Comparable, and it will still work. Sometimes, you will see this be done in-line, using lambda functions. A lambda function is essentially a nameless function that you can define within the line of code, which calls it. They are useful when you only need to call a function for one specific instance and don’t want to define a whole separate function elsewhere. The SortByName comparator could be defined in-line, using a lambda function, like this:
Collections.sort(colors, (a, b)-> {
          return a.name.compareTo(b.name)});
As you might have guessed, (a, b) represents the parameters of the lambda functions (the two objects to be compared). The -> signifies that what follows is a lambda function definition. That’s about it! You’ve now seen the most popular methods of sorting ArrayLists in Java using the Collections package.