当前位置: 首页 > 知识库问答 >
问题:

如何用Java8收集器求和三层嵌套映射

山乐生
2023-03-14
public enum EHourQuarter {
    FIRST(0, 14, 15),
    SECOND(15, 29, 30),
    THIRD(30, 44, 45),
    FOURTH(45, 59, 60);

    private Integer start;
    private Integer end;
    private Integer value;//this is for UI purposes
}

2020-07-08->{0->{hourquarter.first->5.5,ehourquarter.second->10.2,...},1->{ehourquarter.first->33.2,ehourquarter.second->30.1,...},...}

它是一个整数图(小时:从0到23)的局部日期图,二倍的每小时四分之一图。

我需要得到一个包含每个日期累加的map >,这意味着如果日期2020-07-07到2020-07-10(4天)包含在小时0中,每个小时5为每一小时,那么结果应该显示在小时0中,每个季度的值为20。

另外,如果通过制作这个,您可以帮助我将它映射到像这样的DTO列表中,

public class QuarterlyOccupancyDTO {
    private Integer hour;
    private Integer minute;//this is the value property of EHourQuarter
    private Double occupancy;
}

我不胜感激。

最后,DTO列表应该包含按小时和分钟分组的所有日期的总和(EHourQuarter的value属性)。

{
   "2020-06-26":{
      "0":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "1":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "2":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "3":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "4":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "5":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "6":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "7":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "8":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "9":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "10":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "11":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "12":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "13":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "14":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "15":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "16":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "17":{
         "FOURTH":5.0,
         "FIRST":5.0,
         "THIRD":5.0,
         "SECOND":5.0
      },
      "18":{
         "FOURTH":0.0,
         "FIRST":5.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "19":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "20":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "21":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "22":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      },
      "23":{
         "FOURTH":0.0,
         "FIRST":0.0,
         "THIRD":0.0,
         "SECOND":0.0
      }
   }
}

像这样的列表应该是答案:

[
   {
      "hour":0,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":0,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":0,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":0,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":1,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":1,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":1,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":1,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":2,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":2,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":2,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":2,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":3,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":3,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":3,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":3,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":4,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":4,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":4,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":4,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":5,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":5,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":5,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":5,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":6,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":6,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":6,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":6,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":7,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":7,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":7,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":7,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":8,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":8,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":8,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":8,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":9,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":9,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":9,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":9,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":10,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":10,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":10,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":10,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":11,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":11,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":11,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":11,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":12,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":12,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":12,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":12,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":13,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":13,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":13,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":13,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":14,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":14,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":14,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":14,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":15,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":15,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":15,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":15,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":16,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":16,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":16,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":16,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":17,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":17,
      "minute":30,
      "occupancy":5.0
   },
   {
      "hour":17,
      "minute":45,
      "occupancy":5.0
   },
   {
      "hour":17,
      "minute":60,
      "occupancy":5.0
   },
   {
      "hour":18,
      "minute":15,
      "occupancy":5.0
   },
   {
      "hour":18,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":18,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":18,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":19,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":19,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":19,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":19,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":20,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":20,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":20,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":20,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":21,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":21,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":21,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":21,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":22,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":22,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":22,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":22,
      "minute":60,
      "occupancy":0.0
   },
   {
      "hour":23,
      "minute":15,
      "occupancy":0.0
   },
   {
      "hour":23,
      "minute":30,
      "occupancy":0.0
   },
   {
      "hour":23,
      "minute":45,
      "occupancy":0.0
   },
   {
      "hour":23,
      "minute":60,
      "occupancy":0.0
   }
]

共有1个答案

蒋胡非
2023-03-14

第一组,按小时/季度对计算入住率

(避免嵌套FlatMap,因为它会降低代码的可读性)

Map<Entry<Integer, Integer>, Double> groups
    = map.entrySet()
         .stream()
         // Flatten the outer map, since you don't care about the days
         .flatMap(de -> de.getValue().entrySet().stream())
         // Flatten the map by combining hour key and quarter key into a single one
         .flatMap(he -> he.getValue()
                          .entrySet()
                          .stream()
                          .map(qe -> new SimpleEntry<>(new SimpleEntry<>(he.getKey(), qe.getKey().getValue()), qe.getValue())))
         // Sum the occupancy per each hour/quarter pair
         .collect(groupingBy(Entry::getKey, summingDouble(Entry::getValue)));

然后将分组的条目映射到DTO对象中

List<QuarterlyOccupancyDTO> list =
    groups.entrySet()
          .stream()
          .map(e -> new QuarterlyOccupancyDTO(e.getKey().getKey(), e.getKey().getValue(), e.getValue()))
          .collect(toList());

另一种纯函数方法:

Collection<QuarterlyOccupancyDTO> dtos =
    map.entrySet()
       .stream()
       // Flatten the outer map, since you don't care about the days
       .flatMap(de -> de.getValue().entrySet()
                        .stream())
       // Flatten the map by merging hour key and quarter key into a single one
       .flatMap(he -> he.getValue()
                        .entrySet()
                        .stream()
                        .map(qe -> new SimpleEntry<>(new SimpleEntry<>(he.getKey(), qe.getKey().getValue()),
                                                     qe.getValue())))
       // Map each entry into a DTO object and then reduce the occupancy per each hour/quarter pair
       .collect(
           groupingBy(Entry::getKey,
                      mapping(e -> new QuarterlyOccupancyDTO(e.getKey().getKey(), e.getKey().getValue(), e.getValue()),
                              reducing(new QuarterlyOccupancyDTO(0, 0, 0.0),
                                       (a, b) -> new QuarterlyOccupancyDTO(b.getHour(), b.getMinute(), a.getOccupancy() + b.getOccupancy())))))
       .values();
 类似资料:
  • 我有一个对象的集合,每个对象都有一个元素的集合,例如: 如何使用Java 8函数式编程来过滤和收集类型等于“a”的集合? 我尝试了以下方法: 但我得到以下错误: 变量'filteredChildren'初始值设定项'parents。stream()。forEach(p- 如何按类型筛选嵌套集合并收集它们?

  • 如何使用java8流和过滤器过滤嵌套循环? 假设我有一个汽车列表(

  • 我有一个地图列表,并希望对某些列进行分组和求和。 地图列表:

  • 假设你有一张这样的物体地图(尽管想象它更大): rtype=133,有两个! 我想对Streams做的是这样的: 我在理解Collectors&groupBy的工作原理时遇到了一些麻烦,但我想这可能会用于本例。 在Java streams API中进行编码的正确方法是什么? 我很难找到类似的地图例子(人们在他们的例子中更多地使用列表)

  • 我有一个方法可以返回相当嵌套的JSON,比如: 当我尝试使用< code>JsonSlurper将这个JSON slurp到< code>def result中时,我得到了异常: 当<code>parseText</code>执行时产生引发的异常: 有什么办法吗?

  • 我使用MapStruct来映射我的实体,我使用Mockito来嘲笑我的对象。 我想用MapStruct测试一个包含映射的方法。问题是嵌套映射器在我的单元测试中总是为null(在应用程序中工作得很好)