【问题标题】:How to sort Map<YearMonth, List<LocalDate>> with java 8 lambda and streams如何使用 java 8 lambda 和流对 Map<YearMonth, List<LocalDate>> 进行排序
【发布时间】:2016-07-07 06:44:42
【问题描述】:

我有一个这样的排序日期列表:

2016-07-07
2016-07-08
2016-07-09
2016-07-10
2016-07-11
2016-07-12
2016-07-13
...
2016-07-31
2016-08-01
2016-08-02
2016-08-03
...
2017-01-01
2017-01-02
2017-01-03
...

从这个列表中我生成了一个Map&lt;YearMonth, List&lt;LocalDate&gt;&gt; 流:

Map<YearMonth, List<LocalDate>> d = dates.stream().collect(Collectors.toList())
      .stream().collect(Collectors.groupingBy(date -> YearMonth.from(date)));

该地图的输出如下所示:

{2016-12=[2016-12-01, 2016-12-02,...2016-12-31], 2016-11=[2016-11-01, 2016-11-02,...]}

但我需要的输出应该是这样的:

  • 按日期升序排序的地图键:{2016-07=[...], 2016-08=[...]}
  • 按日期升序排序的映射(列表)值:{2016-07=[2016-07-01, 2016-07-02, ...], 2016-08=[2016-08-01, 2016-08-02, ...]}

我尝试了许多选项来获得预期的结果,但我只是为键或值而不是两者都获得了正确的排序

Map<YearMonth, List<LocalDate>> m = stream().collect(Collectors.toList())
      .stream().sorted((e1,e2) -> e2.compareTo(e1))
      .collect(Collectors.groupingBy(date -> YearMonth.from(date)));

结果:

{2016-07=[2016-07-31, 2016-07-30, ...], 2016-08=[2016-08-31, 2016-08-30, ...]}

如何同时按键和值排序?

【问题讨论】:

    标签: java sorting date java-8 java-stream


    【解决方案1】:

    使用 TreeMap 作为收集器,以便按键对输出进行排序。

    类似这样的:

     dates.stream()
          .sorted()
          .collect(
             Collectors.groupingBy(YearMonth::from, TreeMap::new, Collectors.toList())
          );
    

    【讨论】:

      【解决方案2】:

      Collectors.groupingBy(date -&gt; YearMonth.from(date)) 内部将结果存储在 HashMap 中,键排序丢失。

      此实现将保留键顺序:

        Map<YearMonth, List<LocalDate>> d = dates
              .stream()
              .sorted((e1,e2) -> e2.compareTo(e1))
              .collect(Collectors
                      .groupingBy(YearMonth::from,
                              LinkedHashMap::new,
                              Collectors.toList()));
      

      【讨论】:

        【解决方案3】:

        您可以使用返回排序集合的特定Collectors。 在您的情况下,我将使用 TreeMap 按其键对结果 Map 进行排序,并像这样显式对结果值集合进行排序:

        Map<YearMonth, List<LocalDate>> m = dates.stream()
           .collect(Collectors.groupingBy(
                      date -> YearMonth.from(date),
                      TreeMap::new,
                      Collectors.collectingAndThen(
                        Collectors.toList(),
                        (list) -> { Collections.sort(list); return list; })));
        

        【讨论】:

          【解决方案4】:

          您可以按以下方式对它们进行排序:-

          Map<YearMonth, List<LocalDate>> map = dates.stream()
                  .collect(Collectors.toList())
                  .stream()
                  .sorted((e1,e2) -> e1.compareTo(e2))
                  .collect(Collectors.groupingBy(date -> YearMonth.from(date), TreeMap::new, Collectors.toList()));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-07-05
            • 1970-01-01
            相关资源
            最近更新 更多