Java8如何按枚举类型合并多个列表

aelbi1ox  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(529)

如何按枚举类型合并Java8中的多个列表?
我有两个清单:

List<StatusSummary> listA //4 items because we have 4 enum types
List<StatusSummary> listB //4 items because we have 4 enum types

class StatusSummary {
  private StatusEnum resourcesStatus; //4 statuses: TypeA, TypeB, TypeC, TypeD
  private Integer count;
}

我想要一份清单,每个清单上有4个项目 resourcesStatus: TypeA, TypeB, TypeC, TypeD 元素之和 count 字段类型:

List<StatusSummary> listA+B with 4 objects:
(resourcesStatus: TypeA, count: 3), (resourcesStatus: TypeB, count:99), (resourcesStatus: typeC, count:322), (resourcesStatus: TypeD, count:2)

到目前为止,我实现了如下内容:

listA
    .getResourcesStatus()
    .forEach(la -> listB.getResourcesStatus().stream()
        .filter(lb -> lb.getResourcesStatus() == la.getResourcesStatus())
        .forEach(lb -> result.add(new StatusSummary()
            .count(la.getCount() + lb.getCount())
        .status(la.getStatus()))));
smdncfj3

smdncfj31#

你可以用 Collectors.toMap . Map绘制者 ResourcesStatus 合并两个 StatusSummarycount 相同的合并函数中的字段 ResourcesStatus 然后你得到 Map<StatusEnum, StatusSummary> 然后使用 .values()ArrayList .

List<StatusSummary> newList = 
           new ArrayList<>(
                  Stream.of(listA, listB)
                 .flatMap(Collection::stream)
                 .collect(Collectors.toMap(e -> e.getResourcesStatus(), i -> i,
                   (a,b) -> new StatusSummary(a.getResourcesStatus(),
                                                a.getCount() + b.getCount())))
                 .values());
tuwxkamq

tuwxkamq2#

使用问题 forEach 据我所知,您当前的解决方案使用 forEach ,您可以使用streamapi,因为它将是一个简单的for循环,具有其他特性。您违反了javastream的副作用原则,简单地说,流在通过管道执行操作时不应该修改另一个集合。我还没有测试你的代码,但是,这不是你应该处理流的方式。
可能的解决方案之一
你可以用 Collectors.groupingByCollectors.summingInt 得到 Map<StatusEnum, Integer> 状态和计数的总和。然后,每个条目都可以转换为 StatusSummary 并被列为 List :

List<StatusSummary> list = Stream.of(listA, listB)
     .flatMap(List::stream)
     .collect(Collectors.groupingBy(                        // Map<StatusSummary, Integer>
          StatusSummary::getResourcesStatus,                // .. StatusEnum as key
          Collectors.summingInt(StatusSummary::getCount)))  // .. Integer as value (sum)
     .entrySet()
     .stream()                                              // Stream<Entry<..>>
     .map(e -> new StatusSummary(e.getKey(), e.getValue())) // Stream<StatusSummary>
     .collect(Collectors.toList());                         // List<StatusSummary>

... 或使用 Collectors.collectingAndThen (相当详细):

List<StatusSummary> list1 = Stream.of(listA, listB, listC)
    .flatMap(List::stream)
    .collect(Collectors.collectingAndThen(
         Collectors.groupingBy(
             StatusSummary::getResourcesStatus, 
             Collectors.summingInt(StatusSummary::getCount)),
         map -> map.entrySet().stream()
             .map(e -> new StatusSummary(e.getKey(), e.getValue()))
             .collect(Collectors.toList())));

相关问题