说我有这个流:
list.stream()
.map(fn1) // part1
.map(fn2) //
.filter(fn3) //
.flatMap(fn4) // part 2
.map(fn5) //
.filter(fn6) //
.map(fn7) //
.collect(Collectors.toList())
我怎样才能看起来像:
list.stream()
.map(fnPart1)
.map(fnPart2)
.collect(Collectors.toList())
无需手动展开fnX部件并将它们放在一起(出于维护原因,我希望保持它们不受影响,并用它们表达fnPartX)。
答案 0 :(得分:14)
你可以用功能来表达和撰写:
Function<Stream<T1>, Stream<T2>> fnPart1 =
s -> s.map(fn1)
.map(fn2)
.filter(fn3);
Function<Stream<T2>, Stream<T3>> fnPart2 =
s -> s.flatMap(fn4)
.map(fn5)
.filter(fn6)
.map(fn7);
fnPart1.andThen(fnPart2).apply(list.stream()).collect(Collectors.toList());
函数的输入和输出类型必须相应匹配。
这可以作为更复杂的构图构造的基础,例如:
public class Composer<T>{
private final T element;
private Composer(T element){
this.element = element;
}
public <T2> Composer<T2> andThen(Function<? super T, ? extends T2> f){
return new Composer<>(f.apply(element));
}
public T get(){
return element;
}
public static <T> Composer<T> of(T element){
return new Composer<T>(element);
}
}
可以这样使用:
Composer.of(list.stream())
.andThen(fnPart1)
.andThen(fnPart2)
.get()
.collect(Collectors.toList());
答案 1 :(得分:5)
你必须使用flatMap而不是map。我不知道你的类型是什么,所以我称之为T1,T2等。
list.stream()
.flatMap(fnPart1)
.flatMap(fnPart2)
.collect(Collectors.toList())
Stream<T2> fnPart1(T1 t1) {
return Stream.of(t1).map(fn1).map(fn2).filter(fn3);
}
Stream<T3> fnPart2(T2 t2) {
return Stream.of(t2).flatMap(fn4).map(fn5).filter(fn6).map(fn7);
}
当然你可以删除一些流操作:
Stream<T2> fnPart1(T1 t1) {
return Stream.of(fn2(fn1(t1))).filter(fn3);
}
Stream<T3> fnPart2(T2 t2) {
return fn4(t2).map(fn5).filter(fn6).map(fn7);
}
由于fnPart1和fnPart2只处理单个元素,因此可以进一步简化。