Question
I want to sort an ArrayList of custom Java objects by one of their properties, which is a Date returned by getStartDate().
I have read about sorting ArrayList objects using a Comparator, but many examples use compareTo(), which confused me because I thought that method was mainly associated with types like String.
Usually, I compare two dates like this:
item1.getStartDate().before(item2.getStartDate())
So I was wondering whether I could create a comparator like this:
public class CustomComparator {
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
}
public class RandomName {
// ...
Collections.sort(Database.arrayList, new CustomComparator());
// ...
}
What is the correct way to sort an ArrayList of custom objects by a Date field in Java?
Short Answer
By the end of this page, you will understand how sorting works in Java for custom objects, why Comparator uses an int-returning compare() method instead of a boolean, and how to sort an ArrayList by a Date property safely and clearly.
Concept
In Java, sorting works by asking one question repeatedly: which of these two items should come first?
For custom objects, Java cannot guess the correct order unless you tell it how to compare them. That is where a Comparator comes in.
A Comparator<T> is an object that defines sorting rules for type T. Its compare(T a, T b) method must return:
- a negative number if
ashould come beforeb - 0 if they are equal for sorting purposes
- a positive number if
ashould come afterb
This is why returning boolean is incorrect. Sorting needs more than just true/false. It needs to know whether one item is less than, equal to, or greater than another.
compareTo() is related, but it is not only for String. Many Java classes implement Comparable, including String, Integer, and Date. For example, Date already has a method.
Mental Model
Think of sorting like arranging index cards on a desk.
Each card is a custom object. Java picks up two cards at a time and asks your comparator:
- Should card A go before card B?
- Should card B go before card A?
- Or are they equal in order?
A boolean answer is too limited because it only gives part of the story. Java needs a full ranking answer:
- negative = A first
- zero = same position
- positive = B first
So a comparator is like a sorting rulebook that explains how to order your objects based on one property, such as a start date.
Syntax and Examples
Basic comparator syntax
import java.util.Comparator;
public class CustomComparator implements Comparator<MyItem> {
@Override
public int compare(MyItem item1, MyItem item2) {
return item1.getStartDate().compareTo(item2.getStartDate());
}
}
Then use it like this:
Collections.sort(myList, new CustomComparator());
Complete example
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
class Event {
private String name;
private Date startDate;
public Event(String name, Date startDate) {
this.name = name;
this.startDate = startDate;
}
public String getName() {
name;
}
Date {
startDate;
}
String {
name + + startDate;
}
}
<Event> {
{
e1.getStartDate().compareTo(e2.getStartDate());
}
}
{
{
ArrayList<Event> events = <>();
events.add( (, (, , )));
events.add( (, (, , )));
events.add( (, (, , )));
Collections.sort(events, ());
(Event event : events) {
System.out.println(event);
}
}
}
Step by Step Execution
Consider this code:
ArrayList<Event> events = new ArrayList<>();
events.add(new Event("A", new Date(124, 4, 20)));
events.add(new Event("B", new Date(124, 4, 18)));
events.add(new Event("C", new Date(124, 4, 25)));
events.sort(Comparator.comparing(Event::getStartDate));
What happens step by step
- Java stores three
Eventobjects in the list. events.sort(...)starts the sorting process.- Java compares pairs of
Eventobjects. - For each comparison, it calls
getStartDate()on both objects. - The comparator compares the two
Dateobjects. - If the first date is earlier, it returns a negative value.
Real World Use Cases
Sorting custom objects by a property is extremely common.
Examples
- Calendar apps: sort events by start date
- Task managers: sort tasks by due date
- E-commerce systems: sort orders by creation time
- Messaging apps: sort conversations by latest message date
- Logging tools: sort log entries by timestamp
- Booking systems: sort reservations by check-in date
Why comparators are useful
A single object can be sorted in different ways depending on the feature:
- by date
- by name
- by priority
- by price
Using a Comparator lets you define different sorting rules without changing the class itself.
Real Codebase Usage
In real projects, developers often use comparators in a few common patterns.
1. Sorting by one field
users.sort(Comparator.comparing(User::getCreatedAt));
2. Sorting by multiple fields
If two dates are the same, sort by name:
events.sort(
Comparator.comparing(Event::getStartDate)
.thenComparing(Event::getName)
);
3. Handling null values safely
If some dates may be null:
events.sort(
Comparator.comparing(Event::getStartDate, Comparator.nullsLast(Date::compareTo))
);
4. Early validation before sorting
Developers often validate data before sorting:
if (events == null || events.isEmpty()) {
return;
}
events.sort(Comparator.comparing(Event::getStartDate));
5. Keeping comparison logic reusable
A comparator may be stored as a constant:
public static final Comparator<Event> BY_START_DATE =
Comparator.comparing(Event::getStartDate);
This makes sorting rules easier to reuse across services, controllers, and tests.
Common Mistakes
1. Returning boolean from compare()
This is incorrect:
public boolean compare(Object object1, Object object2) {
return object1.getStartDate().before(object2.getStartDate());
}
Why it is wrong:
Comparator.compare()must returnint- sorting needs three outcomes, not just true/false
2. Not implementing Comparator<T>
Broken example:
public class CustomComparator {
public int compare(MyItem a, MyItem b) {
return a.getStartDate().compareTo(b.getStartDate());
}
}
This defines a method, but the class does not actually implement Comparator<MyItem>.
Correct version:
public <MyItem> {
{
a.getStartDate().compareTo(b.getStartDate());
}
}
Comparisons
Comparator vs Comparable
| Feature | Comparator | Comparable |
|---|---|---|
| Where sorting logic lives | Outside the class | Inside the class |
| Method | compare(a, b) | compareTo(other) |
| Return type | int | int |
| Good for multiple sort orders | Yes | No |
| Good for natural/default order | Sometimes | Yes |
before() vs compareTo() for
Cheat Sheet
Quick rules
- Use
Comparator<T>to sort custom objects. compare(T a, T b)must return anint.- Return:
- negative if
acomes first 0if equal- positive if
bcomes first
- negative if
Datealready implementsComparable<Date>.- For dates, use
date1.compareTo(date2)inside the comparator.
Common syntax
Comparator class
class EventDateComparator implements Comparator<Event> {
@Override
public int compare(Event e1, Event e2) {
return e1.getStartDate().compareTo(e2.getStartDate());
}
}
Sort with Collections.sort
Collections.sort(events, ());
FAQ
Can I sort custom objects in Java without changing the class?
Yes. Use a Comparator when you want to define sorting outside the class.
Why does Comparator.compare() return int instead of boolean?
Because sorting needs to know whether one item is less than, equal to, or greater than another.
Is compareTo() only for String?
No. Many Java classes implement Comparable, including String, Integer, and Date.
How do I sort by a Date field in Java?
Use a comparator that compares the date values, such as:
Comparator.comparing(MyClass::getStartDate)
What if two objects have the same date?
The comparator returns 0 for that comparison. You can add a second rule with thenComparing() if needed.
Should I use Collections.sort() or ?
Mini Project
Description
Create a small Java program that manages a list of events and sorts them by their start date. This project demonstrates how to define custom objects, store them in an ArrayList, and order them using a comparator.
Goal
Build a program that prints events in chronological order based on a Date property.
Requirements
- Create an
Eventclass withnameandstartDatefields. - Add at least four
Eventobjects to anArrayList. - Sort the list by
startDatefrom earliest to latest. - Print the sorted events to the console.
Keep learning
Related questions
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Choosing a @NotNull Annotation in Java: Validation vs Static Analysis
Learn how Java @NotNull annotations differ, when to use each one, and how to choose between validation, IDE hints, and static analysis tools.
Convert a Java Stack Trace to a String
Learn how to convert a Java exception stack trace to a string using StringWriter and PrintWriter, with examples and common mistakes.