Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java groupingBy:使用单个流获取两个(或更多)组_Java_Java 8_Functional Programming_Java Stream_Vavr - Fatal编程技术网

Java groupingBy:使用单个流获取两个(或更多)组

Java groupingBy:使用单个流获取两个(或更多)组,java,java-8,functional-programming,java-stream,vavr,Java,Java 8,Functional Programming,Java Stream,Vavr,如果我必须使用Stream基于两个不同的字段生成两个组,我可以采用以下方法: var prop1Group = beans.stream().collect(Collectors.groupingBy(Bean::getProp1)); var prop2Group = beans.stream().collect(Collectors.groupingBy(Bean::getProp2)); 但这种方法会在列表上迭代两次。 以一种强制性的方式,我可以在一次迭代中得到相同的结果,如下所示: v

如果我必须使用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);
}
var prop1Group=newhashmap();
var prop2Group=new HashMap();
for(变量bean:bean){
prop1Group.computeIfAbsent(bean.getProp1(),key->newHashSet()).add(bean);
prop2Group.computeIfAbsent(bean.getProp2(),key->newHashSet()).add(bean);
}

还有什么方法可以使用streams以声明的方式完成相同的任务,而不需要重复两次吗?

根据@Holger的评论,我可以用teeing更声明性地编写它,就像这样,但这仍然需要2N

beans.stream().collect(
                Collectors.teeing(
                        groupingBy(Bean::getProp1),
                        groupingBy(Bean::getProp2),
                        List::of)) 

既然您已经添加了
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)))
));
在这种情况下,组将存储为Java 12中的
Tuple2

字段,但是,我不认为“迭代两次”是普通集合的实际问题。这听起来更像是过早的优化。事实上,考虑到JIT和Hotspot优化器的工作方式,解决方案迭代两次但在内部循环中执行一个操作可能会更快。