Java 按降序排列日期

Java 按降序排列日期,java,sorting,date,Java,Sorting,Date,我正在尝试根据列表中的日期字段按降序对数组列表进行排序。以下是我如何提取字符串格式的日期列表: 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.

我正在尝试根据列表中的日期字段按降序对数组列表进行排序。以下是我如何提取字符串格式的日期列表:

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));
}

然后,我在网上找到了它们,但我不确定如何将它们实际应用到我的案例中,因为我的案例没有对象,因此我无法执行类似于
Collections.sort的操作(myList,new Comparator{}
),我使用下面的代码按降序对其进行排序:

     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;
    });

我相信你可以通过否定比较来改变顺序

      return -1*(o2.get(3).compareTo(o1.get(3)));

最佳解决方案:正确进行数据建模。对列表中的对象使用适当的类,而不是内部列表。在该类中,对日期使用
LocalDate
。避免使用
Date
类,因为它早已过时,尽管它的名称不代表日期,但代表时间点,这不是您需要的。是否r类应该实现
Comparable
,或者应该使用comparator进行排序,这是一个设计决策,我不能根据我掌握的信息给出建议。你可以在那里找到很多很好的例子

可能有非常特殊的情况表明列表就在这里,同样,我也没有信息可以告诉你,但大多数情况下并非如此

如果每个日期最多出现一次,则第二个最佳解决方案是:将所有内部列表放入
TreeMap
,其中
LocalDate
对象作为键和
Comparator.reverseOrder()
作为比较器。再次避免
Date
,当然也要避免
SimpleDateFormat
。后一类是出了名的麻烦。使用
DateTimeFormatter
将日期字符串解析为
LocalDate
对象。然后将映射中的所有值放到一个列表中,并按desc中的日期进行排序结束顺序。使用这种方式,每个日期将只解析一次,而不是每次比较。由于您的数据中有2017年10月16日的两次,请修改此解决方案,使映射值为列表列表,而不仅仅是列表(字符串)

糟糕的解决方案:使用比较器对列表进行排序,该比较器从每个内部列表中取出索引3处的元素,对其进行解析并进行比较。使用以下比较器:

        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/uuuu");
        Comparator<List<String>> descendingDateComparator = Comparator
                .comparing((List<String> l) -> LocalDate.parse(l.get(3), dateFormatter))
                .reversed();
DateTimeFormatter dateFormatter=DateTimeFormatter.of模式(“MM/dd/uuu”);
比较器下降日期比较器=比较器
.comparing((列表l)->LocalDate.parse(l.get(3),dateFormatter))
.reversed();

使用
Comparator。比较
和friends来指定一个比较器不仅更简洁,而且最重要的是不容易出错。

列表也是对象。千万不要将日期作为美式格式的字符串进行比较使用
Comparator
进行解析您应该使用与日期字符串匹配的格式模式字符串(在这种情况下,没有时间)。您应该对日期对象进行排序,最好是
LocalDate
,而不是日期字符串。在任何情况下,您都应该避免使用过时且臭名昭著的
SimpleDateFormat
类。我建议改为使用它的
DateTimeFormatter
。这是事实,@shmosel,但
List
接口没有扩展
Comparable
,因此链接问题的第一个答案不会按现状运行。当然,列表可以排序,例如使用比较器。在所有情况下,将数据作为列表列表在我看来都是糟糕的数据建模,尽管我们没有足够的背景来判断。是的,这就是我的意思;-)是的,在你发布答案之前我也弄明白了!谢谢!为什么有必要使用
1*
呢?你可以直接否定这个表达式。或者通过交换
o1
o2
来反转比较。你需要在比较之前将字符串转换为日期对象。例如:“11/05/2014”>“10/16/2017”串form@Jaycee非常感谢!但是我从上面的编辑中得到了未处理的解析异常。然后,如果我添加了catch语句,我会在返回处得到“错误的返回类型:布尔值不能转换为int”!该行的格式化程序噢~您可以将布尔值转换为整数您可以进行此更改“return formatter.parse(o2.get(3))。compareTo((formatter.parse(o1.get(3));“感谢您提供了自己的解决方案。它将不起作用。您需要决定空值在排序顺序中的位置。您就像试图说“只是把它们放在某个地方”,这可能会导致排序引发异常。对于具有相同日期的行,也要保持值的一致性(我建议您从比较器返回0)。
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/uuuu");
        Comparator<List<String>> descendingDateComparator = Comparator
                .comparing((List<String> l) -> LocalDate.parse(l.get(3), dateFormatter))
                .reversed();