将 Stream 映射到包含 Total 的对象列表
Posted
技术标签:
【中文标题】将 Stream 映射到包含 Total 的对象列表【英文标题】:Map Stream to List of Objects With Total 【发布时间】:2021-09-24 21:23:16 【问题描述】:我有一个 Map
是从这段代码中得到的
Map<String, Long> countsMap = sampleObjectList.stream()
.collect(Collectors.groupingBy(sampleObject::getStatus, Collectors.counting()));
获取地图后,我需要创建一个对象列表,其中包含每个状态的计数和总计数。
我使用下面的 for 循环执行此操作的正常方式。
List<ObjectCountDTO> dtoList = new ArrayList<>();
long allCount = 0L;
for(Map.Entry<String, Long> entry : countsMap.entrySet())
long count = entry.getValue();
allCount += count;
dtoList.add(new ObjectCountDTO(entry.getKey(), count));
dtoList.add(new ObjectCountDTO("ALL", allCount));
有没有办法在 java 8 中使用流来做到这一点?
【问题讨论】:
【参考方案1】:你可以stream
频率entrySet
Map
。
List<ObjectCountDTO> dtoList = countsMap.entrySet().stream()
.map(e -> new ObjectCountDTO(e.getKey(), e.getValue()).collect(Collectors.toList());
dtoList.add(new ObjectCountDTO("ALL",
countsMap.values().stream().mapToLong(i->i).sum()));
【讨论】:
是的,这将是正确的,但我在想是否存在仅使用 1 个流的解决方案。如果除了使用超过 1 个流没有其他解决方案,那么只使用 1 个 for 循环不是更好吗? 流并不总是最合适的工具。在这种情况下,使用 for 循环是最高效的。【参考方案2】:如果你想在一个流中做所有事情,你可以使用下面的代码 sn-p
List<ObjectCountDTO> dtoList = new ArrayList<>();
dtoList.add(new ObjectCountDTO("ALL", countsMap.entrySet().stream()
.map(e ->
dtoList.add(new ObjectCountDTO(e.getKey(), e.getValue()));
return e;
)
.map(e -> e.getValue())
.reduce(0L, (a, b) -> a + b)));
【讨论】:
以上是关于将 Stream 映射到包含 Total 的对象列表的主要内容,如果未能解决你的问题,请参考以下文章