koflox
koflox

Reputation: 71

Sort Java collection relative to the current date

I want to sort my List of Date relative to the current date, e.g we have next items in list:

10.01.2018, 
10.20.2018, 
10.14.2018, 
10.02.2018 

and the current date is 10.08.2018.

The result should be ascending sort of array in the next order:

10.14.2018, 
10.20.2018    and then 
10.01.2018, 
10.02.2018. 

First should be dates that didn't happen and then the past dates. How to do it with Comparator?

Upvotes: 6

Views: 1689

Answers (3)

fps
fps

Reputation: 34460

The most concise and elegant, yet readable way I've found is as follows:

list.sort(
    Comparator
    .comparing( LocalDate.now()::isAfter )
    .thenComparing( Comparator.naturalOrder() )
);

This reads as sort by first comparing whether each date is after today or not, then break ties using LocalDate's natural order. (It's worth remembering that sorting boolean values means putting falses at the beginning and trues at the end, i.e. false < true).

Upvotes: 7

Alexander Pankin
Alexander Pankin

Reputation: 3955

    LocalDate now = LocalDate.now();

    List<LocalDate> dates = Arrays.asList(
            LocalDate.parse("2018-10-02"),
            LocalDate.parse("2018-10-20"),
            LocalDate.parse("2018-10-14"),
            LocalDate.parse("2018-10-01"));

    // sort relative to the current date
    dates.sort(Comparator.<LocalDate>comparingInt(localDate ->
            localDate.isAfter(now) ? -1 : localDate.isBefore(now) ? 1 : 0)
            // then sort normally
            .thenComparing(Comparator.naturalOrder()));

    System.out.println(dates);

Upvotes: 3

azro
azro

Reputation: 54148

You can see this way

  • if the two dates you're comparing are on the same side (both before or both after) of today, compare them normally
  • if you have one before and one after you need to reverse the order

This will keep ascending order but put future dates before past dates

public static void main(String[] args) {
    List<LocalDate> list = Arrays.asList(
                                      LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 20),
                                      LocalDate.of(2018, 10, 14),LocalDate.of(2018, 10, 2));
    System.out.println(list);
    LocalDate now = LocalDate.now();

    list.sort((o1, o2) -> {
        if (o1.isBefore(now) && o2.isBefore(now) || o1.isAfter(now) && o2.isAfter(now)) {
            return o1.compareTo(o2);
        }
        return o2.compareTo(o1);
    });

    System.out.println(list);
}


[2018-10-01, 2018-10-20, 2018-10-14, 2018-10-02]
[2018-10-14, 2018-10-20, 2018-10-01, 2018-10-02]

Upvotes: 2

Related Questions