是否可以在Java 8中使用for
重构以下Stream
循环?
在收集不同来源的清单时,将状态从内部移动到外部?
Map<StateEnum, List<List<ThreadDo>>> stateDumpListMap = new HashMap<>();
for (ThreadDumpDo dumpDo : dumpDoList) {
Map<StateEnum, List<ThreadDo>> stateDoListMap = getStateGroup(dumpDo);
stateDoListMap.entrySet().stream().forEach(entry -> {
stateDumpListMap.putIfAbsent(entry.getKey(), new ArrayList<>());
stateDumpListMap.get(entry.getKey()).add(entry.getValue());
});
}
最近我尝试了几个用例,但这对我来说似乎很难看。
我尝试使用stream().map()
来实现这一目标,但我失败了。有人可以帮忙吗?
答案 0 :(得分:3)
以下是一种方法,使用collect
代替forEach
来生成Map
,并使用flatMap
来消除for
循环:
Map<StateEnum, List<List<ThreadDo>>> stateDumpListMap =
dumpDoList.stream ()
.flatMap (d->getStateGroup(d).entrySet().stream ())
.collect(Collectors.toMap (Map.Entry::getKey,
e -> {
List<List<ThreadDo>> l = new ArrayList<>();
l.add (e.getValue());
return l;
},
(v1,v2)->{v1.addAll(v2);return v1;}));
正如Aominè评论的那样,可以简化为:
Map<StateEnum, List<List<ThreadDo>>> stateDumpListMap =
dumpDoList.stream ()
.flatMap (d->getStateGroup(d).entrySet().stream ())
.collect(Collectors.toMap (Map.Entry::getKey,
e -> new ArrayList<>(Collections.singletonList(e.getValue())),
(v1,v2)->{v1.addAll(v2);return v1;}));
答案 1 :(得分:1)
试试这个:
Map<StateEnum, List<List<ThreadDo>>> stateDumpListMap = dumpDoList.stream()
.flatMap(dumpDo -> getStateGroup(dumpDo).entrySet().stream())
.collect(Collectors.groupingBy(
entry -> entry.getKey(),
Collectors.mapping(entry -> entry.getValue(), Collectors.toList())));
答案 2 :(得分:1)
另一个选项,collect
:
Map<StateEnum, List<List<ThreadDo>>> stateDumpListMap = dumpDoList.stream()
.map(this::getStateGroup) // dumpDo mapped to stateDoListMap ( Map<StateEnum, List<ThreadDo>> )
.map(Map::entrySet) // stream of sets of entries of stateDoListMap (Entry<StateEnum, List<ThreadDo>>)
.flatMap(Set::stream) // stream of entries of all stateDoListMaps
.collect(HashMap::new, // collect to a new HashMap, types infered from the variable declaration
(map, stateDoListMapEntry) -> map.computeIfAbsent(stateDoListMapEntry.getKey(), key -> new ArrayList<>()).add(stateDoListMapEntry.getValue()), // for each entry incoming from the stream, compute it if does not exist in the target map yet (create the top level list), then add List<ThreadDo> to it.
Map::putAll);
三参数collect
允许指定它返回的映射的精确实现。可能有也可能没有必要控制它 - 取决于你需要的地图。