Menu
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

Java Tutorial

Java HOME Java Intro Java Get Started Java Syntax Java Output Java Comments Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Math Java Booleans Java If...Else Java Switch Java While Loop Java For Loop Java Break/Continue Java Arrays

Java Methods

Java Methods Java Method Parameters Java Method Overloading Java Scope Java Recursion

Java Classes

Java OOP Java Classes/Objects Java Class Attributes Java Class Methods Java Constructors Java Modifiers Java Encapsulation Java Packages / API Java Inheritance Java Polymorphism Java Inner Classes Java Abstraction Java Interface Java Enums Java User Input Java Date Java ArrayList Java LinkedList Java List Sorting Java HashMap Java HashSet Java Iterator Java Wrapper Classes Java Exceptions Java RegEx Java Threads Java Lambda Java Advanced Sorting

Java File Handling

Java Files Java Create/Write Files Java Read Files Java Delete Files

Java How To's

Add Two Numbers Count Words Reverse a String Sum of Array Elements Convert String to Array Sort an Array Find Array Average Find Smallest Element ArrayList Loop HashMap Loop Loop Through an Enum Area of Rectangle Even or Odd Number Positive or Negative Square Root Random Number

Java Reference

Java Reference Java Keywords Java String Methods Java Math Methods Java Output Methods Java Arrays Methods Java ArrayList Methods Java LinkedList Methods Java HashMap Methods Java Scanner Methods Java Iterator Methods Java Errors & Exceptions

Java Examples

Java Examples Java Compiler Java Exercises Java Quiz Java Server Java Syllabus Java Certificate


Java Advanced Sorting (Comparator and Comparable)


Java Advanced Sorting

In the List Sorting Chapter, you learned how to sort lists alphabetically and numerically, but what if the list has objects in it?

To sort objects you need to specify a rule that decides how objects should be sorted. For example, if you have a list of cars you might want to sort them by year, the rule could be that cars with an earlier year go first.

The Comparator and Comparable interfaces allow you to specify what rule is used to sort objects.

Being able to specify a sorting rule also allows you to change how strings and numbers are sorted.


Comparators

An object that implements the Comparator interface is called a comparator.

The Comparator interface allows you to create a class with a compare() method that compares two objects to decide which one should go first in a list.

The compare() method should return a number which is:

  • Negative if the first object should go first in a list.
  • Positive if the second object should go first in a list.
  • Zero if the order does not matter.

A class that implements the Comparator interface might look something like this:

// Sort Car objects by year
class SortByYear implements Comparator {
  public int compare(Object obj1, Object obj2) {
    // Make sure that the objects are Car objects
    Car a = (Car) obj1;
    Car b = (Car) obj2;
    
    // Compare the objects
    if (a.year < b.year) return -1; // The first car has a smaller year
    if (a.year > b.year) return 1;  // The first car has a larger year
    return 0; // Both cars have the same year
  }
}

To use the comparator, pass it as an argument into a sorting method:

// Use a comparator to sort the cars
Comparator myComparator = new SortByYear();
Collections.sort(myCars, myComparator);

Here is a complete example using a comparator to sort a list of cars by year:

Example

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

// Define a Car class
class Car {
  public String brand;
  public String model;
  public int year;
  
  public Car(String b, String m, int y) {
    brand = b;
    model = m;
    year = y;
  }
}

// Create a comparator
class SortByYear implements Comparator {
  public int compare(Object obj1, Object obj2) {
    // Make sure that the objects are Car objects
    Car a = (Car) obj1;
    Car b = (Car) obj2;
    
    // Compare the year of both objects
    if (a.year < b.year) return -1; // The first car has a smaller year
    if (a.year > b.year) return 1;  // The first car has a larger year
    return 0; // Both cars have the same year
  }
}

public class Main { 
  public static void main(String[] args) { 
    // Create a list of cars
    ArrayList<Car> myCars = new ArrayList<Car>();    
    myCars.add(new Car("BMW", "X5", 1999));
    myCars.add(new Car("Honda", "Accord", 2006));
    myCars.add(new Car("Ford", "Mustang", 1970));

    // Use a comparator to sort the cars
    Comparator myComparator = new SortByYear();
    Collections.sort(myCars, myComparator);

    // Display the cars
    for (Car c : myCars) {
      System.out.println(c.brand + " " + c.model + " " + c.year);
    }
  } 
}
Try it Yourself »

Using a Lambda Expression

To make the code shorter, the comparator can be replaced with a lambda expression which has the same arguments and return value as the compare() method:

Example

Use a lambda expression as a comparator:

Collections.sort(myCars, (obj1, obj2) -> {
  Car a = (Car) obj1;
  Car b = (Car) obj2;
  if (a.year < b.year) return -1;
  if (a.year > b.year) return 1;
  return 0;
});
Try it Yourself »

Special Sorting Rules

Comparators can also be used to make special sorting rules for strings and numbers. In this example we use a comparator to list all of the even numbers before the odd ones:

Example

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class SortEvenFirst implements Comparator {
  public int compare(Object obj1, Object obj2) {
    // Make sure the objects are integers
    Integer a = (Integer)obj1;
    Integer b = (Integer)obj2;
    
    // Check each number to see if it is even
    // A number is even if the remainder when dividing by 2 is 0
    boolean aIsEven = (a % 2) == 0;
    boolean bIsEven = (b % 2) == 0;
    
    if (aIsEven == bIsEven) {
    
      // If both numbers are even or both are odd then use normal sorting rules
      if (a < b) return -1;
      if (a > b) return 1;
      return 0;
      
    } else {
    
      // If a is even then it goes first, otherwise b goes first
      if (aIsEven) {
      	return -1;
      } else {
        return 1;
      }
    }
  }
}

public class Main {
  public static void main(String[] args) {
    ArrayList<Integer> myNumbers = new ArrayList<Integer>();
    myNumbers.add(33);
    myNumbers.add(15);
    myNumbers.add(20);
    myNumbers.add(34);
    myNumbers.add(8);
    myNumbers.add(12);

    Comparator myComparator = new SortEvenFirst();
    Collections.sort(myNumbers, myComparator);

    for (int i : myNumbers) {
      System.out.println(i);
    }
  }
}
Try it Yourself »

The Comparable Interface

The Comparable interface allows an object to specify its own sorting rule with a compareTo() method.

The compareTo() method takes an object as an argument and compares the comparable with the argument to decide which one should go first in a list.

Like the comparator, the compareTo() method returns a number which is:

  • Negative if the comparable should go first in a list.
  • Positive if the other object should go first in a list.
  • Zero if the order does not matter.

Many native Java classes implement the Comparable interface, such as String and Integer.

This is why strings and numbers do not need a comparator to be sorted.

An object that implements the Comparable interface might look something like this:

class Car implements Comparable {
  public String brand;
  public String model;
  public int year;
  
  // Decide how this object compares to other objects
  public int compareTo(Object obj) {
  	Car other = (Car)obj;
    if(year < other.year) return -1; // This object is smaller than the other one
    if(year > other.year) return 1;  // This object is larger than the other one
    return 0; // Both objects are the same
  }
}

Here is the same example as before but using the Comparable interface instead of a comparator:

Example

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

// Define a Car class which is comparable
class Car implements Comparable {
  public String brand;
  public String model;
  public int year;
  
  public Car(String b, String m, int y) {
    brand = b;
    model = m;
    year = y;
  }
  
  // Decide how this object compares to other objects
  public int compareTo(Object obj) {
  	Car other = (Car)obj;
    if(year < other.year) return -1; // This object is smaller than the other one
    if(year > other.year) return 1;  // This object is larger than the other one
    return 0; // Both objects are the same
  }
}

public class Main { 
  public static void main(String[] args) { 
    // Create a list of cars
    ArrayList<Car> myCars = new ArrayList<Car>();    
    myCars.add(new Car("BMW", "X5", 1999));
    myCars.add(new Car("Honda", "Accord", 2006));
    myCars.add(new Car("Ford", "Mustang", 1970));

    // Sort the cars
    Collections.sort(myCars);

    // Display the cars
    for (Car c : myCars) {
      System.out.println(c.brand + " " + c.model + " " + c.year);
    }
  } 
}
Try it Yourself »

A Common Sorting Trick

The most obvious way to sort two numbers naturally is to write something like this:

if(a.year < b.year) return -1; // a is less than b
if(a.year > b.year) return 1; // a is greater than b
return 0; // a is equal to b

But it can actually be done with just a single line:

return a.year - b.year;

This trick can also be used to easily sort things in reverse:

return b.year - a.year;

Comparator vs. Comparable

A comparator is an object with one method that is used to compare two different objects.

A comparable is an object which can compare itself with other objects.

It is easier to use the Comparable interface when possible, but the Comparator interface is more powerful because it allows you to sort any kind of object even if you cannot change its code.




×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
[email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
[email protected]

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2024 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.