是否可以避免在同一个集合中的当前流内创建流,如下面的示例中收集一些数据(使用 listOfA 两次来创建流)?
List<A> listOfA = Arrays.asList(new A(1L, "A1", "V1"), new A(2L, "A2", "V1"), new A(1L, "A1", "V2"));
List<B> listOfB = listOfA.stream().map(r -> new B(r.getId(), r.getName(),
listOfA.stream().filter(r2 -> r.getId().equals(r2.getId())).map(A::getVal).collect(toSet())
)).distinct().collect(toList());
class A {
private final Long id;
private final String name;
private final String val;
A(Long id, String name, String val) //constructor
//getters
}
class B {
private final Long id;
private final String name;
private final Set<String> values;
B(Long id, String name, Set<String> values) //constructor
//getters
@Override
public boolean equals(Object o) {
...
return id.equals(a.id);
}
//hashCode
}
最终结果应该是 2 个对象的列表:
B{id=1, name='A1', 值=[V1, V2]}
B{id=2,名称='A2',值=[V1]
提前致谢!
最佳答案
不知道你问这个问题的目的是什么。如果问题是为了避免重新创建流而需要进行的最小更改是什么,那么我必须回答:我不知道。但是,您的方法似乎过于复杂。外链map
, collect
, filter
, distinct
和collect
在那里 build 的东西真的很难理解。
简短的咆哮之后......
也许我担心 future 的 Java 程序都会像这样,从而变得完全不可维护,这是没有道理的。也许人们只是“习惯”这种编程风格。也许有一个短暂的时期,当人们过于渴望使用新的语言功能时,它迟早会回到“正常”风格(以及功能元素的“健康”水平)。但我个人认为像
block 引用>createBsByMergingTheValuesOfAs()
这样的方法在这里就足够并且合适了。...我建议使用专用的
Collector
,它已经提供了许多用于可变减少的基础设施,您似乎正在通过此操作链来模拟:import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; public class StreamCollectTest { public static void main(String[] args) { List<A> listOfA = Arrays.asList( new A(1L, "A1", "V1"), new A(2L, "A2", "V1"), new A(1L, "A1", "V2")); Map<Long, B> result = listOfA.stream().collect( Collectors.toConcurrentMap( // The "id" will be the key of the map a -> a.getId(), // The initial value stored for each key will be a "B" // whose set of values contains only the element of // the corresponding "A" a -> new B(a.getId(), a.getName(), new LinkedHashSet<String>(Collections.singleton(a.getVal()))), // Two "B"s with the same key will be merged by adding // all values from the second "B" to that of the first (b0,b1) -> { b0.values.addAll(b1.values); return b0; })); System.out.println(result); } static class A { private final Long id; private final String name; private final String val; A(Long id, String name, String val) { this.id = id; this.name = name; this.val = val; } public Long getId() { return id; } public String getName() { return name; } public String getVal() { return val; } } static class B { private final Long id; private final String name; private final Set<String> values; B(Long id, String name, Set<String> values) { this.id = id; this.name = name; this.values = values; } @Override public String toString() { return id+","+name+","+values; } } }
打印
{1=1,A1,[V1, V2], 2=2,A2,[V1]}
所以
values()
生成的 map 应该正是您正在寻找的内容。
关于java 8 lambda - 多次使用流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24490033/