Assuming you actually have a List<AnObject>, all you need is

list.sort(Comparator.comparing(a -> a.attr));

If you make you code clean by not using public fields, but accessor methods, it becomes even cleaner:

list.sort(Comparator.comparing(AnObject::getAttr));
Answer from JB Nizet on Stack Overflow
🌐
JavaTechOnline
javatechonline.com › home › how to sort the list in java 8
How To Sort The List In Java 8 - JavaTechOnline
January 29, 2026 - Here, we will cover almost all commonly used ways to implement sorting and comparison especially using Java 8. When we use the approaches of sorting a list using Java 8, we can save too many lines of code for sure. When we have custom objects to sort then we have to provide the comparator implementation, we can replace it with lambda to make the code shorter and more readable.
Top answer
1 of 15
187

(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;
}
🌐
Medium
medium.com › @joyantonyrebello › java-sort-a-list-by-multiple-attributes-example-874e94ba0d6b
Java - Sort a List by multiple attributes example | by Joy Antony Rebello | Medium
June 7, 2020 - The key points here are this comparator takes a list of comparators passed via its constructor; and the compare() method iterates over this comparators list to compare two Employee objects by each individual comparator. Now, we create separate comparators for each field by which we want to sort: job title, age and salary. ... As we can see, the list of employees is sorted firstly by job title, secondly by age, and finally salary, in ascending order. The Apache Commons Lang API provides the CompareToBuilder class that can be used to sort a list collection by multiple attributes in a much simpler way.
🌐
CodeJava
codejava.net › java-core › collections › sorting-a-list-by-multiple-attributes-example
Java Sort a List by multiple attributes example
===== SORTING BY MULTIPLE ATTRIBUTES ===== *** Before sorting: Tom Developer 45 80000 Sam Designer 30 75000 Bob Designer 45 134000 Peter Programmer 25 60000 Tim Designer 45 130000 Craig Programmer 30 52000 Anne Programmer 25 51000 Alex Designer 30 120000 Bill Programmer 22 30000 Samuel Developer 28 80000 John Developer 35 67000 Patrick Developer 35 140000 Alice Programmer 35 80000 David Developer 35 99000 Jane Designer 30 82000 *** After sorting: Sam Designer 30 75000 Jane Designer 30 82000 Alex Designer 30 120000 Tim Designer 45 130000 Bob Designer 45 134000 Samuel Developer 28 80000 John Dev
🌐
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 - 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
🌐
javaspring
javaspring.net › blog › java-8-sort-list-of-objects-by-attribute-without-custom-comparator
Java 8: How to Sort List of Objects by Attribute Without Custom Comparator – Clean & Short Method
Java 8 revolutionized this process with the introduction of lambda expressions, method references, and new APIs in the Comparator interface. These features allow you to sort lists by object attributes in a concise, clean manner—without writing ...
🌐
Nichost
ab-sneg.nichost.ru › how-to-fqiqj › vpsi---java-8-sort-list-of-objects-by-multiple-attributes---xx5.html
Java 8 sort list of objects by multiple attributes
Java 8 - Sorting stream on multiple fields, Java 8 example to sort stream of objects by multiple fields using Java stream sort on multiple fields – example. 0-specific features (such as zip or list comprehensions), so it can be used for Python 1. Group By, Count and Sort. Hi, Am trying to sort a Map based on a value object's attribute.
Find elsewhere
🌐
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 - Java 8 example to sort stream of objects by multiple fields using comparators and Comparator.thenComparing() method. This method returns a lexicographic-order comparator with another comparator.
🌐
CodingTechRoom
codingtechroom.com › question › how-to-sort-a-collection-of-objects-by-multiple-properties-in-java
How to Sort a List of Objects by Multiple Attributes in Java? - CodingTechRoom
Define separate `Comparator` implementations for each attribute you want to sort by (e.g., name, age, country). Optionally, use lambda expressions or method references for more succinct comparator definitions (Java 8 and later).
🌐
JavaTechOnline
javatechonline.com › home › java 8 sort list of objects by multiple attributes
Java 8 Sort List Of Objects By Multiple Attributes Archives - JavaTechOnline
May 10, 2020 - Moreover, we have also provided an example which was being used before the introduction of Java 8. Hence our article is on 'How To Sort the List in Java 8'. There are multiple ways to sort a list of items already available before Java8. Further, Java8 has introduced different ways to make sorting/comparison easy.
Top answer
1 of 16
166

Using Comparator

For Example:

class Score {

    private String name;
    private List<Integer> scores;
    // +accessor methods
}

    Collections.sort(scores, new Comparator<Score>() {

        public int compare(Score o1, Score o2) {
            // compare two instance of `Score` and return `int` as result.
            return o2.getScores().get(0).compareTo(o1.getScores().get(0));
        }
    });

With Java 8 onwards, you can simply use lambda expression to represent Comparator instance.

Collections.sort(scores, (s1, s2) -> { /* compute and return int */ });
2 of 16
153

Either make ActiveAlarm implement Comparable<ActiveAlarm> or implement Comparator<ActiveAlarm> in a separate class. Then call:

Collections.sort(list);

or

Collections.sort(list, comparator);

In general, it's a good idea to implement Comparable<T> if there's a single "natural" sort order... otherwise (if you happen to want to sort in a particular order, but might equally easily want a different one) it's better to implement Comparator<T>. This particular situation could go either way, to be honest... but I'd probably stick with the more flexible Comparator<T> option.

EDIT: Sample implementation:

public class AlarmByTimesComparer implements Comparator<ActiveAlarm> {
  @Override
  public int compare(ActiveAlarm x, ActiveAlarm y) {
    // TODO: Handle null x or y values
    int startComparison = compare(x.timeStarted, y.timeStarted);
    return startComparison != 0 ? startComparison
                                : compare(x.timeEnded, y.timeEnded);
  }

  // I don't know why this isn't in Long...
  private static int compare(long a, long b) {
    return a < b ? -1
         : a > b ? 1
         : 0;
  }
}
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."

🌐
CopyProgramming
copyprogramming.com › howto › java-8-sort-list-of-objects-by-attribute-without-custom-comparator
Sorting a List of Objects by Attribute in Java - Sort list of objects by attribute java
January 25, 2026 - You need multiple different sort orders for the same type (e.g., by name, salary, date). You cannot modify the class to add Comparable (third‑party types). You want to keep sorting logic separate from the domain object. Modern code favors Comparator.comparing plus method references rather than separate comparator classes in most scenarios. Modern Java (8–21) encourages a concise, expressive style for sorting collections, with clear performance and readability benefits.
🌐
Java67
java67.com › 2017 › 07 › how-to-sort-arraylist-of-objects-using.html
How to Sort ArrayList of Objects by Fields in Java? Custom + Reversed Order Sorting Comparator Example | Java67
In order to sort the list of courses ... upon fee. These Comparator implementation classes use Java 8 lambdas to implement compare() method as shown here, and sort the list of objects into ascending order of title and ...
Top answer
1 of 16
1736

Since Date implements Comparable, it has a compareTo method just like String does.

So your custom Comparator could look like this:

public class CustomComparator implements Comparator<MyObject> {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
}

The compare() method must return an int, so you couldn't directly return a boolean like you were planning to anyway.

Your sorting code would be just about like you wrote:

Collections.sort(Database.arrayList, new CustomComparator());

A slightly shorter way to write all this, if you don't need to reuse your comparator, is to write it as an inline anonymous class:

Collections.sort(Database.arrayList, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
});

Since java-8

You can now write the last example in a shorter form by using a lambda expression for the Comparator:

Collections.sort(Database.arrayList, 
                        (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

And List has a sort(Comparator) method, so you can shorten this even further:

Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

This is such a common idiom that there's a built-in method to generate a Comparator for a class with a Comparable key:

Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));

All of these are equivalent forms.

2 of 16
202

Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).

Two examples:

public class Number implements Comparable<Number> {
    private int value;

    public Number(int value) { this.value = value; }
    public int compareTo(Number anotherInstance) {
        return this.value - anotherInstance.value;
    }
}

public class Chair {
    private int weight;
    private int height;

    public Chair(int weight, int height) {
        this.weight = weight;
        this.height = height;
    }
    /* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getWeight() - chair2.getWeight();
    }
}
class ChairHeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getHeight() - chair2.getHeight();
    }
}

Usage:

List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);

List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());

// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
    public int compare(Chair chair1, Chair chair2) {
        ...
    }
});
🌐
Coderanch
coderanch.com › t › 690271 › java › Sorting-objects-multiple-attributes
Sorting objects by multiple attributes (Beginning Java forum at Coderanch)
Comparator is the right tool for the job. The requirement is to create a method of type void sortByFirstName() to StudentList class, so I believe that can't be done using Compare? Is it possible to sort an object by multiple attributes without using the Comparator interface?
🌐
YouTube
youtube.com › watch
How to Sort an Objects List Based on Attributes in Java - YouTube
Discover how to effectively sort a list of objects in Java based on multiple attributes using a max value approach. Learn step-by-step with clear examples an...
Published   September 6, 2025
Views   2
🌐
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 - Input: A list of Employee objects with salary and name. Output: A list sorted first by salary (ascending), and if salaries are equal, by name (alphabetically). Define the Employee Class: Create an Employee class with attributes like name and salary.