Your Comparator would look like this:

public class GraduationCeremonyComparator implements Comparator<GraduationCeremony> {
    public int compare(GraduationCeremony o1, GraduationCeremony o2) {
        int value1 = o1.campus.compareTo(o2.campus);
        if (value1 == 0) {
            int value2 = o1.faculty.compareTo(o2.faculty);
            if (value2 == 0) {
                return o1.building.compareTo(o2.building);
            } else {
                return value2;
            }
        }
        return value1;
    }
}

Basically it continues comparing each successive attribute of your class whenever the compared attributes so far are equal (== 0).

Answer from Daniel DiPaolo on Stack Overflow
Top answer
1 of 6
76

Your Comparator would look like this:

public class GraduationCeremonyComparator implements Comparator<GraduationCeremony> {
    public int compare(GraduationCeremony o1, GraduationCeremony o2) {
        int value1 = o1.campus.compareTo(o2.campus);
        if (value1 == 0) {
            int value2 = o1.faculty.compareTo(o2.faculty);
            if (value2 == 0) {
                return o1.building.compareTo(o2.building);
            } else {
                return value2;
            }
        }
        return value1;
    }
}

Basically it continues comparing each successive attribute of your class whenever the compared attributes so far are equal (== 0).

2 of 6
43

Yes, you absolutely can do this. For example:

public class PersonComparator implements Comparator<Person>
{
    public int compare(Person p1, Person p2)
    {
        // Assume no nulls, and simple ordinal comparisons

        // First by campus - stop if this gives a result.
        int campusResult = p1.getCampus().compareTo(p2.getCampus());
        if (campusResult != 0)
        {
            return campusResult;
        }

        // Next by faculty
        int facultyResult = p1.getFaculty().compareTo(p2.getFaculty());
        if (facultyResult != 0)
        {
            return facultyResult;
        }

        // Finally by building
        return p1.getBuilding().compareTo(p2.getBuilding());
    }
}

Basically you're saying, "If I can tell which one comes first just by looking at the campus (before they come from different campuses, and the campus is the most important field) then I'll just return that result. Otherwise, I'll continue on to compare faculties. Again, stop if that's enough to tell them apart. Otherwise, (if the campus and faculty are the same for both people) just use the result of comparing them by building."

🌐
Baeldung
baeldung.com › home › java › java collections › sort collection of objects by multiple fields in java
Sort Collection of Objects by Multiple Fields in Java | Baeldung
January 8, 2024 - We’ll be comparing Person objects first based on name and then on age throughout our examples: public class Person { @Nonnull private String name; private int age; // constructor // getters and setters } Here, we’ve added a @Nonnull annotation to keep the examples simple. But in production code, we may need to handle the comparison of nullable fields. Java provides the Comparator interface for comparing two objects of the same type.
Discussions

java - Collections.sort with multiple fields - Stack Overflow
(originally from Ways to sort lists of objects in Java based on multiple fields) ... Java 8 solves this nicely by lambda's (though Guava and Apache Commons might still offer more flexibility): More on stackoverflow.com
🌐 stackoverflow.com
Sorting a list of objects using multiple fields (Java 8) - Stack Overflow
Communities for your favorite technologies. Explore all Collectives · Stack Overflow for Teams is now called Stack Internal. Bring the best of human thought and AI automation together at your work More on stackoverflow.com
🌐 stackoverflow.com
sorting - Sort a Java collection object based on one field in it - Stack Overflow
I have the following collection: Collection agentDtoList = new ArrayList (); Where AgentSummaryDTO looks like this: public class AgentSummaryDTO imple... More on stackoverflow.com
🌐 stackoverflow.com
List.contains() for objects with multiple fields
Have you looked into overriding the equals and hash methods of Thing so that sort of thing is automated? Also look into sets if you want a DS that doesn't accept duplicate objects. More on reddit.com
🌐 r/javahelp
7
0
February 6, 2021
🌐
Benchresources
benchresources.net › home › java › java 8 – sorting list of objects on multiple fields
Java 8 - Sorting list of objects on multiple fields - BenchResources.Net
October 18, 2022 - A comparison function, which imposes a total ordering on some collection of objects · Comparators can be passed to a sort method (such as Collections.sort or Arrays.sort) to allow precise control over the sort order · Using Java 8 Comparator, we are going to sort list of Customer objects on the basis of three attributes viz.; name, city and their age
🌐
Java67
java67.com › 2021 › 09 › java-comparator-multiple-fields-example.html
How to sort a List or Stream by Multiple Fields in Java? Comparator comparing() + thenComparing Example | Java67
If your natural ordering requires multiple fields comparing then go for it, otherwise use a Comparator. In general, the code for sorting which defines natural order is implemented using Comparable and resides in the same class but Comparator ...
🌐
Medium
bindushrestha.medium.com › how-to-order-list-of-objects-using-multiple-fields-b0b67c610613
How to sort list of objects using multiple fields? | by Bindu Shrestha | Medium
May 10, 2022 - private List<Student> sortWithLambdaExp(List<Student> list) {// sort using stream and firstNamelist.sort(Comparator.comparing((Student s) -> s.getStream()).thenComparing((Student s) -> s.getFirstName()));return list;}
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › sorting a stream by multiple fields in java
Sorting a Stream by Multiple Fields in Java - Group by sort example
March 10, 2022 - This method returns a ... BY clause. To sort on multiple fields, we must first create simple comparators for each field on which we want to sort the stream items....
Top answer
1 of 15
190

(originally from Ways to sort lists of objects in Java based on multiple fields)

Original working code in this gist

Using Java 8 lambda's (added April 10, 2019)

Java 8 solves this nicely by lambda's (though Guava and Apache Commons might still offer more flexibility):

Collections.sort(reportList, Comparator.comparing(Report::getReportKey)
            .thenComparing(Report::getStudentNumber)
            .thenComparing(Report::getSchool));

Thanks to @gaoagong's answer below.

Note that one advantage here is that the getters are evaluated lazily (eg. getSchool() is only evaluated if relevant).

Messy and convoluted: Sorting by hand

Collections.sort(pizzas, new Comparator<Pizza>() {  
    @Override  
    public int compare(Pizza p1, Pizza p2) {  
        int sizeCmp = p1.size.compareTo(p2.size);  
        if (sizeCmp != 0) {  
            return sizeCmp;  
        }  
        int nrOfToppingsCmp = p1.nrOfToppings.compareTo(p2.nrOfToppings);  
        if (nrOfToppingsCmp != 0) {  
            return nrOfToppingsCmp;  
        }  
        return p1.name.compareTo(p2.name);  
    }  
});  

This requires a lot of typing, maintenance and is error prone. The only advantage is that getters are only invoked when relevant.

The reflective way: Sorting with BeanComparator

ComparatorChain chain = new ComparatorChain(Arrays.asList(
   new BeanComparator("size"), 
   new BeanComparator("nrOfToppings"), 
   new BeanComparator("name")));

Collections.sort(pizzas, chain);  

Obviously this is more concise, but even more error prone as you lose your direct reference to the fields by using Strings instead (no typesafety, auto-refactorings). Now if a field is renamed, the compiler won’t even report a problem. Moreover, because this solution uses reflection, the sorting is much slower.

Getting there: Sorting with Google Guava’s ComparisonChain

Collections.sort(pizzas, new Comparator<Pizza>() {  
    @Override  
    public int compare(Pizza p1, Pizza p2) {  
        return ComparisonChain.start().compare(p1.size, p2.size).compare(p1.nrOfToppings, p2.nrOfToppings).compare(p1.name, p2.name).result();  
        // or in case the fields can be null:  
        /* 
        return ComparisonChain.start() 
           .compare(p1.size, p2.size, Ordering.natural().nullsLast()) 
           .compare(p1.nrOfToppings, p2.nrOfToppings, Ordering.natural().nullsLast()) 
           .compare(p1.name, p2.name, Ordering.natural().nullsLast()) 
           .result(); 
        */  
    }  
});  

This is much better, but requires some boiler plate code for the most common use case: null-values should be valued less by default. For null-fields, you have to provide an extra directive to Guava what to do in that case. This is a flexible mechanism if you want to do something specific, but often you want the default case (ie. 1, a, b, z, null).

And as noted in the comments below, these getters are all evaluated immediately for each comparison.

Sorting with Apache Commons CompareToBuilder

Collections.sort(pizzas, new Comparator<Pizza>() {  
    @Override  
    public int compare(Pizza p1, Pizza p2) {  
        return new CompareToBuilder().append(p1.size, p2.size).append(p1.nrOfToppings, p2.nrOfToppings).append(p1.name, p2.name).toComparison();  
    }  
});  

Like Guava’s ComparisonChain, this library class sorts easily on multiple fields, but also defines default behavior for null values (ie. 1, a, b, z, null). However, you can’t specify anything else either, unless you provide your own Comparator.

Again, as noted in the comments below, these getters are all evaluated immediately for each comparison.

Thus

Ultimately it comes down to flavor and the need for flexibility (Guava’s ComparisonChain) vs. concise code (Apache’s CompareToBuilder).

Bonus method

I found a nice solution that combines multiple comparators in order of priority on CodeReview in a MultiComparator:

class MultiComparator<T> implements Comparator<T> {
    private final List<Comparator<T>> comparators;

    public MultiComparator(List<Comparator<? super T>> comparators) {
        this.comparators = comparators;
    }

    public MultiComparator(Comparator<? super T>... comparators) {
        this(Arrays.asList(comparators));
    }

    public int compare(T o1, T o2) {
        for (Comparator<T> c : comparators) {
            int result = c.compare(o1, o2);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }

    public static <T> void sort(List<T> list, Comparator<? super T>... comparators) {
        Collections.sort(list, new MultiComparator<T>(comparators));
    }
}

Ofcourse Apache Commons Collections has a util for this already:

ComparatorUtils.chainedComparator(comparatorCollection)

Collections.sort(list, ComparatorUtils.chainedComparator(comparators));
2 of 15
156

Do you see anything wrong with the code?

Yes. Why are you adding the three fields together before you compare them?

I would probably do something like this: (assuming the fields are in the order you wish to sort them in)

@Override public int compare(final Report record1, final Report record2) {
    int c;
    c = record1.getReportKey().compareTo(record2.getReportKey());
    if (c == 0)
       c = record1.getStudentNumber().compareTo(record2.getStudentNumber());
    if (c == 0)
       c = record1.getSchool().compareTo(record2.getSchool());
    return c;
}
Find elsewhere
🌐
Instanceofjava
instanceofjava.com › 2017 › 04 › sort-list-of-objects-by-multiple-fields.html
How to Sort list of objects by multiple fields in java - InstanceOfJava
April 23, 2017 - Create arraylist object and add Student objects with different values into list. Using Collections.Sort(List,FiledComparator) pass corresponding comparator class in order to sort multiple fields of a class.
🌐
Java Guides
javaguides.net › 2024 › 09 › java-8-lambda-for-sorting-list-of-objects-by-multiple-fields.html
Java 8 Lambda for Sorting a List of Objects by Multiple Fields
September 9, 2024 - In Java 8, lambda expressions make this type of sorting simple and concise. You can chain multiple Comparator conditions using thenComparing() to sort by more than one field. ... Defines a list of Employee objects.
🌐
DevGenius
blog.devgenius.io › sorting-an-array-of-object-by-multiple-fields-in-java-and-javascript-e66f0366fc71
Sorting an Array of Objects by Multiple Fields in Java and JavaScript | by Pratiyush Prakash | Dev Genius
July 6, 2025 - Let’s say we have an array of Employee objects. Where Employee is a class with two field (name and salary). First problem is to sort the array based on salary. This I am assuming we all know. So we can do something like this. // let's assume we have an array of Employee - employees // Employee is a class of two fields (String name, int salary)Arrays.sort(employees, (a,b) -> a.salary - b.salary); Second problem is to sort the array based on salary and then name.
🌐
amitph
amitph.com › home › java › sorting collection of objects by multiple fields in java
Sorting Collection of Objects by Multiple Fields in Java - amitph
February 10, 2026 - This tutorial demonstrates several strategies we can implement to sort a Collection of Objects using multiple fields. Let’s create a class Student with a couple of fields. @RequiredArgsConstructor class Student { private final long id; private final String name; private final int age; }Code language: PHP (php) We will compare two Student instances based on their name and age. Let’s create a Java Collection containing a few instances of our Student class. List<Student> collection = List.of( new Student(1L, "Ray", 18), new Student(2L, "Bee", 18), new Student(3L, "Ray", 17), new Student(4L, "Bia", 15), new Student(5L, "Ria", 19) );Code language: PHP (php)
🌐
javaspring
javaspring.net › blog › java-sort-list-of-objects-by-field
Java: Sorting a List of Objects by a Field — javaspring.net
Sorting a list of objects by a field in Java can be achieved using either the Comparable or Comparator interfaces. The Comparable interface is useful when you have a natural ordering for the objects, while the Comparator interface provides more ...
🌐
Javaprogramto
javaprogramto.com › 2020 › 08 › java-8-sorting-stream-on-multiple-fields.html
Java 8 – Sorting Stream On Multiple Fields with Comparator.thenComparing()
Sorting based on multiple fields, you first have to create the two comparators using Comparator.comparing() method and next call Comparator.thenComparing() method. Finally, pass the final comparator to the Collections.sort() method. package ...
🌐
Medium
medium.com › @AlexanderObregon › sorting-lists-in-java-using-collections-sort-14b150ac8682
Sorting Lists in Java Using Collections.sort | Medium
June 4, 2025 - A comparator tells Java how two items should be compared during the sort. It answers the basic question: should this go before or after that? Comparators are flexible. You can use them to sort objects by one field, multiple fields, or even change the order entirely.
🌐
Makeinjava
makeinjava.com › home › sort objects on multiple fields /properties – comparator interface (lambda stream java 8)
Sort object on multiple fields/properties-Comparator (lamda stream java8)
January 3, 2024 - compareToIgnoreCase(person2.firstName) ) .forEach( person-> System.out.println(person) ); //Sort by first and last name System.out.println("\n2.Sort list of person objects by firstName then " + "by lastName then by age"); Comparator<Person> sortByFirstName = (p, o) -> p.firstName.compareToIgnoreCase(o.firstName); Comparator<Person> sortByLastName = (p, o) -> p.lastName.compareToIgnoreCase(o.lastName); Comparator<Person> sortByAge = (p, o) -> Integer.compare(p.age,o.age); //Sort by first Name then Sort by last name then sort by age personList .stream() .sorted( sortByFirstName .thenComparing(sortByLastName) .thenComparing(sortByAge) ) .forEach( person-> System.out.println(person) ); } }
🌐
How to do in Java
howtodoinjava.com › home › java sorting › java comparator thencomparing() example
Java Comparator thenComparing() Example - HowToDoInJava
August 30, 2022 - Java example of sorting a List of objects by multiple fields using Comparator.thenComparing() method. This method returns a lexicographic-order Comparator with another specified Comparator.
🌐
CodeJava
codejava.net › java-core › collections › sorting-a-list-by-multiple-attributes-example
Java Sort a List by multiple attributes example
Java code example to sort a list collection by multiple attributes (keys) of its elements type using a chained comparator or a CompareToBuilder.
🌐
Amir Boroumand
steelcityamir.com › blog › sort-list-of-objects-by-field-java
Sort a List of Objects by Field in Java · Amir Boroumand | Software engineer based in Pittsburgh, PA
May 9, 2018 - This option doesn’t allow for sorting on a different field other than the one we chose. Instead of modifying our class, we can pass in a comparator to Collections.sort(). The examples below create a comparator using an anonymous class. We swap the order of u1 and u2 to reverse the sort order. This option allows code outside the class to dictate the sort criteria and order. However, it requires an ugly anonymous class that isn’t very readable. Java 8 introduced a sort method in the List interface which can use a comparator.