[java] Sort objects in ArrayList by date?

Every example I find is about doing this alphabetically, while I need my elements sorted by date.

My ArrayList contains objects on which one of the datamembers is a DateTime object. On DateTime I can call the functions:

lt() // less-than
lteq() // less-than-or-equal-to

So to compare I could do something like:

if(myList.get(i).lt(myList.get(j))){
    // ...
}

What should I do inside the if block?

This question is related to java sorting datetime

The answer is


All the answers here I found to be un-neccesarily complex for a simple problem (at least to an experienced java developer, which I am not). I had a similar problem and chanced upon this (and other) solutions, and though they provided a pointer, for a beginner I found as stated above. My solution, depends on where in the the Object your Date is, in this case, the date is the first element of the Object[] where dataVector is the ArrayList containing your Objects.

Collections.sort(dataVector, new Comparator<Object[]>() {
    public int compare(Object[] o1, Object[] o2) {
        return ((Date)o1[0]).compareTo(((Date)o2[0]));
    }
});

Since Java 8 the List interface provides the sort method. Combined with lambda expression the easiest solution would be

// sort DateTime typed list
list.sort((d1,d2) -> d1.compareTo(d2));
// or an object which has an DateTime attribute
list.sort((o1,o2) -> o1.getDateTime().compareTo(o2.getDateTime()));
// or like mentioned by Tunaki
list.sort(Comparator.comparing(o -> o.getDateTime()));

Reverse sorting

Java 8 comes also with some handy methods for reverse sorting.

//requested by lily
list.sort(Comparator.comparing(o -> o.getDateTime()).reversed());

The Date class already implements Comparator interface. Assuming you have the class below:

public class A {

    private Date dateTime;

    public Date getDateTime() {
        return dateTime;
    }

    .... other variables

}

And let's say you have a list of A objects as List<A> aList, you can easily sort it with Java 8's stream API (snippet below):

import java.util.Comparator;
import java.util.stream.Collectors;

...

aList = aList.stream()
        .sorted(Comparator.comparing(A::getDateTime))
        .collect(Collectors.toList())

This may be an old response but I used some examples from this post to create a comparator that would sort an ArrayList of HashMap<String, String> by one object in the list, that being the timestamp.

I have these objects:

ArrayList<Map<String, String>> alList = new ArrayList<Map<String, String>>();

The map objects are as follows:

Map<String, Object> map = new HashMap<>();
        // of course this is the actual formatted date below in the timestamp
        map.put("timestamp", "MM/dd/yyyy HH:mm:ss"); 
        map.put("item1", "my text goes here");
        map.put("item2", "my text goes here");

That mapping is what I use to load all my objects into the array list, using the alList.add(map) function, within a loop.

Now, I created my own comparator:

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

 public class DateSorter implements Comparator {
     public int compare(Object firstObjToCompare, Object secondObjToCompare) {
    String firstDateString = ((HashMap<String, String>) firstObjToCompare).get("timestamp");
    String secondDateString = ((HashMap<String, String>) secondObjToCompare).get("timestamp");

    if (secondDateString == null || firstDateString == null) {
        return 0;
    }

    // Convert to Dates
    DateTimeFormatter dtf = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
    DateTime firstDate = dtf.parseDateTime(firstDateString);
    DateTime secondDate = dtf.parseDateTime(secondDateString);

    if (firstDate.isAfter(secondDate)) return -1;
    else if (firstDate.isBefore(secondDate)) return 1;
    else return 0;
    }
}

I can now just call the Comparator at any time on the array and it will sort my array, giving me the Latest timestamp in position 0 (top of the list) and the earliest timestamp at the end of the list. New posts get put to the top basically.

Collections.sort(alList, new DateSorter());

This may help someone out, which is why I posted it. Take into consideration the return statements within the compare() function. There are 3 types of results. Returning 0 if they are equal, returning >0 if the first date is before the second date and returning <0 if the first date is after the second date. If you want your list to be reversed, then just switch those two return statements! Simple =]


Pass the ArrayList In argument.

    private static void order(ArrayList<Object> list) {

    Collections.sort(list, new Comparator() {

        public int compare(Object o2, Object o1) {

            String x1 =  o1.Date;
            String x2 =  o2.Date;

                return  x1.compareTo(x2);

        }
    });
}

Future viewers, I think this is the simplest solution, if your model contains a string type date ("2020-01-01 10:00:00" for example), then just write the following line to sort the data by date descending from newest to the oldest:

Collections.sort(messages, (o1, o2) -> o2.getMessageDate().compareTo(o1.getMessageDate()));

Use the below approach to identify dates are sort or not

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");

boolean  decendingOrder = true;
    for(int index=0;index<date.size() - 1; index++) {
        if(simpleDateFormat.parse(date.get(index)).getTime() < simpleDateFormat.parse(date.get(index+1)).getTime()) {
            decendingOrder = false;
            break;
        }
    }
    if(decendingOrder) {
        System.out.println("Date are in Decending Order");
    }else {
        System.out.println("Date not in Decending Order");
    }       
}   

Here's the answer of how I achieve it:

Mylist.sort(Comparator.comparing(myClass::getStarttime));

With introduction of Java 1.8, streams are very useful in solving this kind of problems:

Comparator <DateTime> myComparator = (arg1, arg2) 
                -> {
                    if(arg1.lt(arg2)) 
                       return -1;
                    else if (arg1.lteq(arg2))
                       return 0;
                    else
                       return 1;
                   };

ArrayList<DateTime> sortedList = myList
                   .stream()
                   .sorted(myComparator)
                   .collect(Collectors.toCollection(ArrayList::new));

You can use Collections.sort method. It's a static method. You pass it the list and a comparator. It uses a modified mergesort algorithm over the list. That's why you must pass it a comparator to do the pair comparisons.

Collections.sort(myList, new Comparator<MyObject> {
   public int compare(MyObject o1, MyObject o2) {
      DateTime a = o1.getDateTime();
      DateTime b = o2.getDateTime();
      if (a.lt(b)) 
        return -1;
      else if (a.lteq(b)) // it's equals
         return 0;
      else
         return 1;
   }
});

Note that if myList is of a comparable type (one that implements Comparable interface) (like Date, Integer or String) you can omit the comparator and the natural ordering will be used.


list.sort(Comparator.comparing(o -> o.getDateTime()));

The best answer IMHO from Tunaki using Java 8 lambda


Given MyObject that has a DateTime member with a getDateTime() method, you can sort an ArrayList that contains MyObject elements by the DateTime objects like this:

Collections.sort(myList, new Comparator<MyObject>() {
    public int compare(MyObject o1, MyObject o2) {
        return o1.getDateTime().lt(o2.getDateTime()) ? -1 : 1;
    }
});

This is how I solved:

Collections.sort(MyList, (o1, o2) -> o1.getLastModified().compareTo(o2.getLastModified()));

Hope it help you.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to sorting

Sort Array of object by object field in Angular 6 Sorting a list with stream.sorted() in Java How to sort dates from Oldest to Newest in Excel? how to sort pandas dataframe from one column Reverse a comparator in Java 8 Find the unique values in a column and then sort them pandas groupby sort within groups pandas groupby sort descending order Efficiently sorting a numpy array in descending order? Swift: Sort array of objects alphabetically

Examples related to datetime

Comparing two joda DateTime instances How to format DateTime in Flutter , How to get current time in flutter? How do I convert 2018-04-10T04:00:00.000Z string to DateTime? How to get current local date and time in Kotlin Converting unix time into date-time via excel Convert python datetime to timestamp in milliseconds SQL Server date format yyyymmdd Laravel Carbon subtract days from current date Check if date is a valid one Why is ZoneOffset.UTC != ZoneId.of("UTC")?