Reputation: 2315
I am trying to sort an array list in descending order according to the date field in the list. Here is how I extracted out the list of dates in string format:
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
List<List<String>> list= viewModel.getAllData(reminderlist);
for(int i = 0; i < list.size(); i++){
System.out.println("DATE " + list.get(i).get(3));
System.out.println("DATE FORMAT " + formatter.parse(list.get(i).get(3));
}
The sample data for the println are:
"09/05/2019", "10/16/2017", "06/24/2020", "10/16/2017", "10/17/2015"
Then, I found some solution online but I not sure how to actually apply them onto my case since mine has no object, therefore I cannot do something like Collections.sort(myList, new Comparator<MyObject> {}
Upvotes: 2
Views: 7363
Reputation: 86232
Best solution: Get your data modeling right. Use a proper class for the objects in your list instead of the inner lists. In that class use LocalDate
for your dates. Avoid the Date
class, it is long outdated and in spite of its name doesn’t represent a date, but a point in time, which is not what you need. Whether your class should implement Comparable
or should be sorted using a comparator is a design decision where I cannot advice based on the information I have. You can find many good examples of both out there.
There may be very special circumstances that dictate that a list of lists is right here, again I don’t have the information to tell, but for the majority of purposes it is not so.
Second best solution if each date occurs at most once: Put all your inner lists into a TreeMap
with LocalDate
objects as keys and Comparator.reverseOrder()
as comparator. Again avoid Date
and certainly avoid SimpleDateFormat
. The latter class is notoriously troublesome. Use a DateTimeFormatter
for parsing the date strings into LocalDate
objects. Then take all the values from the map out into a list, and it will be sorted by the dates in descending order. Using this way each date will only be parsed once instead of each time it is being compared. Since you have October 16, 2017, twice in your data, modify this solution so that the map values are lists of lists rather than just lists (of strings).
Poor solution: Sort your list of lists using a comparator that takes out the element at index 3 from each inner list, parses it and compares it. Use the following comparator:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/uuuu");
Comparator<List<String>> descendingDateComparator = Comparator
.comparing((List<String> l) -> LocalDate.parse(l.get(3), dateFormatter))
.reversed();
Using Comparator.comparing
and friends for specifying a comparator is not just terser, it is first and foremost less error-prone.
Upvotes: 0
Reputation: 2315
I managed to sort it in descending order by using the code below:
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
Collections.sort(templateDirs, (o1, o2) -> {
if (o1.get(3) == null || o2.get(3) == null)
return 0;
try {
boolean b = formatter.parse(o1.get(3)).before(formatter.parse(o2.get(3)));
return b ? 1:-1 ;
} catch (ParseException e) {
e.printStackTrace();
}
return 0;
});
Upvotes: 1
Reputation: 2596
I believe you can just negate the comparison to switch the order. Something like
return -1*(o2.get(3).compareTo(o1.get(3)));
Upvotes: 4