Sorting objects in Java

Mohebullah Mir
Strategio
Published in
4 min readJan 25, 2023

Whenever you’re working with an object-oriented programing language such as Java, chances are you’ll be working with objects, of course. An object is an instance of a class that has its own state (data), behavior (methods), and identity. Now, if you’re working with objects, eventually you will have to sort said objects. Why? You may ask. Sorting data helps us search quickly for information and provides a better representation of the data to easily analyze and understand. Now we’ll dive into the two main ways we can sort data in Java.

Implementing the Comparable interface

Before we go in-depth, I just want to go over the class for the object instances that we’ll be sorting.

class Player implements Comparable<Player> {
private String name;
private int goals;
private int assists;

Player(String name, int goals, int assists) {
this.name = name;
this.goals = goals;
this.assists = assists;
}

public String getName() {
return name;
}

public int getGoals() {
return goals;
}

public int getAssists() {
return assists;
}
...
}

Class Player represents football/soccer (now is not the time to debate over which is correct) players with fields that store the name, goals, and assists for each player. There are also some basic getter methods. Now let's say we have a few Player objects and we want to store them in an array and sort the players based on their scoring capabilities. So the highest-scoring player will come before the lower-scoring players in the array. If two players have the same amount of goals, then we’ll place the player with more assists first. We only need two steps to achieve this with the comparable interface.

  1. Implement the Comparable interface in the class we want to sort.
class Player implements Comparable<Player> {...}

Note: It’s best to use generics and place Player within diamond brackets after comparable for strong typing. (Comparing to Player instead of Object)

2. Override the compareTo method from the Comparable interface.

The compareTo method from the Comparable interface indicates relative ordering between the current object and the received object.

The return type indicates which object will be ordered first:

  1. Negative: The current object will be ordered first.
  2. Positive: The received object will be ordered first.
  3. Zero: Current and received are equal.

Tip: If you’re having trouble wrapping your head around this, then just think a negative return value means the objects won’t swap and a positive return value means the objects will swap.

Knowing this we can implement our compareTo method to order Players by their goals in descending order and if two goals are tied, order by greater assists.

public int compareTo(Player other){
//Subtracting the received objects goals by current goals will sort in descending order.
int result = other.goals - goals;
//If goals are equal, order by assists, otherwise return original result.
return result == 0 ? other.assists - assists : result;
}

Now, all we have to do is initialize our players, place them in an array and sort the array with Arrays.sort().

public static void main(String[] args) {
//Player(Name, Goals, Assists)
Player a = new Player("Messi",8,10);
Player b = new Player("Mbappe",6,2);
Player c = new Player("Ronaldo",10,8);
Player d = new Player("Neymar",6,4);
Player e = new Player("Modric",2,7);
Player[] players = {a,b,c,d,e};

Arrays.sort(players);

Let’s print the array and see the order of players.

for(Player p: players){
System.out.println(p.getName() + "\t--> Goals:" +
p.getGoals() +" Assists:" + p.getAssists());
}
Ronaldo -->  Goals:10 Assists:8
Messi --> Goals:8 Assists:10
Neymar --> Goals:6 Assists:4
Mbappe --> Goals:6 Assists:2
Modric --> Goals:2 Assists:7

As we can see, Ronaldo comes in first with 10 goals, followed by Messi with 8. Neymar and Mbappe both have the same amount of goals, but Neymar was ordered first because he had 4 assists. Sweet! looks like our sorting has been successful.

Implementing the Comparator functional interface

With the Comparator functional interface, we don’t have to implement anything with the class itself. We just need to initialize the interface where we’re sorting.

Sorting with Comparator in three steps:

  1. Initialize the Comparator interface with the type you want to sort.
  2. Override the interface with your new compare method implementation.
  3. Pass the comparator in as a parameter when you call the sort() algorithm.
Comparator<Player> playerComparator = new Comparator<>(){
public int compare(Player p1,Player p2){
int result = p2.getGoals() - p1.getGoals();
return result == 0 ? p2.getAssists() - p1.getAssists() : result;
}
};
Arrays.sort(players,playerComparator);

Not too shabby, right? This can be simplified even further using a lambda expression:

Comparator<Player> playerComparator = (p1,p2) -> {
int result = p2.getGoals() - p1.getGoals();
return result == 0 ? p2.getAssists() - p1.getAssists() : result;
};
Arrays.sort(players,playerComparator);

And if we print the results, the order remains exactly how we expected:

Ronaldo -->  Goals:10 Assists:8
Messi --> Goals:8 Assists:10
Neymar --> Goals:6 Assists:4
Mbappe --> Goals:6 Assists:2
Modric --> Goals:2 Assists:7

Both methods are effective ways of sorting objects in Java, choosing which is a matter of preference. Keep in mind, however, that Comparator may be useful if you will want to sort your objects in many different ways or if you want to sort objects of different classes. You can create a comparator for each sorting implementation and just pass it to the sorting algorithm.

Wow, if you made it this far then that means I haven’t bored you to death! Thank you for reading my article. Feel free to add a comment and follow me if you like the content.

--

--

Mohebullah Mir
Strategio

Software Engineer 💻 Avid Hiker 🌳 Fitness enthusiast 🏋️‍♀️