排序list <object>取日期,其中日期为字符串类型

时间:2018-11-08 07:57:10

标签: java list sorting collections comparator

我有一个对象列表,数据如下:

public class User {
    public String name;
    public String date;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
}
  • Xyz 2012年11月10日
  • 美国广播公司2012年11月10日
  • Pqr 2012年4月20日
  • 艾克(Ijk)2012年8月24日
  • Mno 2014年5月22日

如何根据String附带的日期对数据(即名称)进行排序。我需要按年份,月份和日期排序。 我尝试使用以下代码,但

List<User> list = The list where i get my data
List<User> listTemp = list.stream()
        .sorted(Comparator.comparing(User::getDate))
        .collect(Collectors.toList());

输出为

  • 2012/8/24

  • 5/22/14

  • 4/20/12
  • 12/11/10
  • 12/11/10

P.s-我无法将String的类型更改为Date。

7 个答案:

答案 0 :(得分:2)

尝试此方法:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
List<User> listTemp = list .stream()
            .sorted((u1, u2) -> LocalDate.parse(u1.getDate(), formatter).compareTo(LocalDate.parse(u2.getDate(), formatter)))
            .collect(Collectors.toList());

答案 1 :(得分:1)

通常在这种情况下,最好将String转换为Date,但是无论如何,这是我的解决方案,无需转换:

List<User> listTemp = list.stream()
            .sorted(Comparator.comparing(u -> {
                String[] s = u.getDate().split("-");
                return s[2] + s[1] + s[0];
            }))
            .collect(Collectors.toList());

P.S显然,我不建议在实际项目中使用它

答案 2 :(得分:1)

首先,您不需要在这里进行String-Date转换。您需要的是一个能够处理您的自定义格式的自定义比较器:

这是工作比较器的示例。注意Comparator.comapring.thenComparing方法。它们使您可以进行连续比较。

假设您的格式为mm/dd/yyyy,下面的代码将可以解决问题。它将首先比较yyyy部分,然后比较mmdd

final String delimiter = "/";
list.stream()
    .sorted((user1, user2) -> {
        String[] date1 = user1.getDate().split(delimiter);
        String[] date2 = user2.getDate().split(delimiter);
        return Comparator.comparing((String[] arr) -> arr[2])
                         .thenComparing(arr -> arr[0])
                         .thenComparing(arr -> arr[1])
                         .compare(date1, date2);
    })
    .collect(Collectors.toList());

较简单的解决方案:

Function<User, String[]> splitDate = u -> u.getDate().split("/");
list.stream()
    .sorted((u1, u2) -> Comparator.comparing((String[] arr) -> arr[2])
                                  .thenComparing(arr -> arr[0])
                                  .thenComparing(arr -> arr[1])
                                  .compare(splitDate.apply(u1), splitDate.apply(u2)))
    .collect(Collectors.toList());

答案 3 :(得分:0)

您可以在User类中实现Comparable接口,然后重写compareTo()方法,以便以所需的顺序对日期进行排序。 compareTo()返回一个-1或1的int值。

答案 4 :(得分:0)

代码不起作用的原因是因为当前正在比较字符串。字符串比较器不是用来比较日期的,我希望可以按照字母顺序或类似的方式进行排序。

我不确定为什么您不能说您不能解析日期字符串并使用日期的比较器,这会使您的生活更加轻松。在执行此操作之前,可能需要先进行一些字符串格式设置,但是您将不得不以任何一种方式进行字符串操作。

如果您绝对不能将字符串解析为日期,则需要通过字符串操作或正则表达式来提取字符串的日期部分。然后,您需要将它们转换为数字。然后,您必须在您的类中实现比较器,并使用生成的数字来按需要在比较器中进行排序。

总体而言,我会尝试找到一种将字符串转换为日期的方法,这对我来说似乎是一种更干净的解决方案。

答案 5 :(得分:0)

请在下面找到工作代码:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
    User2 u1 = new User2("User1","08-11-2018");
    User2 u2 = new User2("User2","09-11-2018");
    List<User2> userList = new ArrayList<User2>();
    userList.add(u2);
    userList.add(u1);
    List<User2> listTemp = userList .stream()
                .sorted((x, y) -> LocalDate.parse(x.getDate(), formatter).compareTo(LocalDate.parse(y.getDate(), formatter)))
                .collect(Collectors.toList());

    listTemp.forEach(user -> {
        System.out.println(user);
    });

答案 6 :(得分:0)

 List<User> user = list.stream().
                        sorted(comparing(User::getName).
                              thenComparing(User::getName)).
                                 collect(Collectors.toList());

上面的代码应该有所帮助。我使用了以下示例数据

Abc 2011年3月24日

Abc 2011年3月19日

Abc 2011年3月21日

这将使您清楚地了解如何进行排序。

名称->年->月->日期

供您参考(如果正在使用),则对流进行的修改不会影响您的原始数据源。因此,上述所有解决方案仅会更改而不是您的 User 对象。