CodeMed
CodeMed

Reputation: 9205

java comparator for two LocalDateTimes

A custom class called MyCustomClass has a property that it s joda LocalDateTime. I need to create a java.util.Comparator class to compare instances of MyCustomClass by their TimeStamp property, which is of type LocalDateTime. I have read several postings on this (including this one), and I have tried all the methods, but none of the methods shown in the answers seem to work. For example, the following several approaches throw compilation errors:

import java.time.temporal.ChronoUnit;
import java.util.Comparator;

import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Period;

import my.app.model.MyCustomClass;

public class MyCustomClassComparator implements Comparator<MyCustomClass>{
    public int compare(MyCustomClass mcc1, MyCustomClass mcc2) {
        //this first attempt throws a return type error for the method.
        return Period.fieldDifference(mcc2.getTimestamp(), mcc1.getTimestamp());
        //This next attempt says that LocalDateTimes are not valid arguments
        Duration.between(mcc2.getTimestamp(), mcc1.getTimestamp());
        //The next approach also says LocalDateTimes are not valid arguments.
        DateTime.parse(mcc2.getTimestamp()), mcc1.getTimestamp()).getSeconds();
        //This boilerplate approach says the minus sign is not valid for LocalDateTime
        return mcc1.getTimestamp() - mcc2.getTimestamp();
    }
}

I intend to use this elsewhere in code like:

List<MyCustomClass> mccs = new ArrayList<MyCustomClass>();
// Sort by time stamp:
Collections.sort(mccs, new MyCustomClassComparator());

How do I write a Comparator class to compare instances of MyCustomClass based on their Joda LocalDateTime properties?

Upvotes: 5

Views: 22181

Answers (3)

Fabio Bonfante
Fabio Bonfante

Reputation: 5188

Given the fact that Comparator is a functional interface, we could have it with a single lambda expression.

Comparator<LocalDateTime> localDateTimeComparator = (o1, o2) -> o1.compareTo(o2);

//Then use the comparator as always....
LocalDateTime minDate = dates.stream()
                             .min(localDateTimeComparator)
                             .orElseThrow(Assertion::Error)
                   

For reuse, a static instance could be helpful

//interfaces are "more static" than classes with "static members" ;-)
public interface MyDateUtils { 

   Comparator<LocalDateTime> localDateTimeComparator = (o1, o2) -> o1.compareTo(o2);

}

Upvotes: 2

Alex Sadler
Alex Sadler

Reputation: 121

If all you need is a comparator instance:

Similar to Iłya Bursov's answer, because LocalDateTime implements comparable, you can use Comparator.comparing

Comparator.comparing(MyCustomClass::getTimestamp)

Upvotes: 12

Iłya Bursov
Iłya Bursov

Reputation: 24229

LocalDateTime implements comparable interface, so you can implement comparator like:

public class MyCustomClassComparator implements Comparator<MyCustomClass> {
    @Override
    public int compare(final MyCustomClass mcc1, final MyCustomClass mcc2) {
        return mcc1.getTimestamp().compareTo(mcc2.getTimestamp());
    }
}

Upvotes: 6

Related Questions