我们可以使用java Stream来重构这个吗?

时间:2018-06-06 07:10:53

标签: java java-8 java-stream

是否可以在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()来实现这一目标,但我失败了。有人可以帮忙吗?

3 个答案:

答案 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允许指定它返回的映射的精确实现。可能有也可能没有必要控制它 - 取决于你需要的地图。