如果我必须使用Stream根据两个不同的字段生成两组,这是我可以采用的一种方法:
var prop1Group = beans.stream().collect(Collectors.groupingBy(Bean::getProp1));
var prop2Group = beans.stream().collect(Collectors.groupingBy(Bean::getProp2));
但是这种方法会遍历整个列表两次。 以命令方式,我可以在单次迭代中获得相同的结果,如下所示:
var prop1Group = new HashMap<String, Set<Bean>>();
var prop2Group = new HashMap<String, Set<Bean>>();
for (var bean : beans) {
prop1Group.computeIfAbsent(bean.getProp1(), key -> new HashSet<>()).add(bean);
prop2Group.computeIfAbsent(bean.getProp2(), key -> new HashSet<>()).add(bean);
}
是否有必要使用流以声明方式完成相同的工作,而无需重复两次?
答案 0 :(得分:1)
根据@Holger的评论,我可以像这样通过teeing更加声明性地编写它,但这仍然要花费2N
=ARRAYFORMULA(IFERROR(REGEXEXTRACT(A2:A, "Verify Pending (\d+)")))
答案 1 :(得分:1)
既然您已经添加了vavr
作为标签,我还想添加另一种解决方案,即使用元组,模式匹配和折叠:
var result = list.foldLeft(
Tuple.of(List.empty(), List.empty()),
(lists, element) -> Match(element).of(
Case($(Bean::getProp1), lists.map1(l -> l.append(element))),
Case($(Bean::getProp2), lists.map2(l -> l.append(element)))
));
在这种情况下,组将存储为Tuple2
的字段。