如何解决foldfold和Java收集有什么区别
此问题针对Vavr(Java的FP库),但可能适用于Scala或其他可以与Java进行比较的FP语言。
Vavr foldLeft
和有什么区别:
-
<U> U foldLeft(U zero,BiFunction<? super U,? super T,? extends U> combiner)
和Java的collect
:
似乎两者都可以达到相同的目的:遍历一个集合(例如Stream<T>
),并在遍历时将结果累加成新的U
(或R
)类型。
乍一看,签名在#参数中有所不同,并且Java collect
似乎打算在并行块中运行。
概念上实际存在哪些差异? Vavr foldLeft
似乎更易于使用。
一个非常愚蠢的例子只是为了说明:
Vavr foldLeft
:
// result = "HelloFunctionalWorld"
String result = Seq("Hello","Functional","World")
.foldLeft(new StringBuilder(),(acc,word) -> acc.append(word))
.toString();
Java collect
:
// result = "HelloFunctionalWorld"
final String result = Arrays.asList("Hello","World").stream()
.collect(
StringBuilder::new,word) -> acc.append(word),StringBuilder::append
)
.toString();
解决方法
概念上实际存在哪些差异?
collect(Supplier<R> supplier,BiConsumer<R,? super T> accumulator,R> combiner)
的Javadoc说:
对此流的元素执行mutable reduction操作。可变归约是其中归约值是可变结果容器(例如
ArrayList
),并且通过更新结果的状态而不是通过替换结果来合并元素。产生的结果等于:R result = supplier.get(); for (T element : this stream) accumulator.accept(result,element); return result;
这里的关键词是可变,因为Vavr不会做任何可变的事情,而是一个功能库。
问题中使用StringBuilder
的示例实际上违反了功能原理。如果您不想遵循功能范式,为什么要使用Vavr?
与foldLeft()
等效的Java Stream是reduce()
,您是正确的,第3个参数是支持并行处理:
// Vavr
<U> U foldLeft(U zero,BiFunction<? super U,? super T,? extends U> combine)
// Java Stream
<U> U reduce(U identity,BiFunction<U,? super T,U> accumulator,BinaryOperator<U> combiner)
如果结果类型与流元素类型相同,则将使用以下替代方法,它们不需要第3个参数即可支持并行处理:
// Vavr
T fold(T zero,BiFunction<? super T,? extends T> combine)
// Java Stream
T reduce(T identity,BinaryOperator<T> accumulator)
更新方法比较:
Vavr
-
T fold(T zero,? extends T> combine)
以任意顺序应用
combine
,因此它必须是 associative 函数。 -
<U> U foldLeft(U zero,? extends U> combine)
从左到右应用值。
等效于{em}顺序模式下的
reduce(identity,accumulator,combiner)
,其中combiner
未使用。有效的combiner
函数支持并行模式。 -
<U> U foldRight(U zero,java.util.function.BiFunction<? super T,? super U,? extends U> combine)
从右到左应用值。
没有等效的Java Stream。
Java流
-
Optional<T> reduce(BinaryOperator<T> accumulator)
以任意顺序应用
accumulator
,因此它必须是 associative 函数。例如。可以将1,2,3,4
的流+
处理为((1+2)+3)+4
(顺序模式),或(1+2)+(3+4)
,1+((2+3)+4)
或任何顺序组合(并行模式)。没有Vavr等效项。
-
T reduce(T identity,BinaryOperator<T> accumulator)
以任意顺序应用
accumulator
,因此它必须是 associative 函数。例如。可以将1,4
和0
的流+
作为(((0+1)+2)+3)+4
(顺序模式)或((0+1)+2) + ((0+3)+4)
或任何顺序组合(并行模式)。 -
<U> U reduce(U identity,BinaryOperator<U> combiner)
按顺序应用值,其中
combiner
支持并行处理。顺序模式等效于foldLeft(zero,combine)`。
-
<R> R collect(Supplier<R> supplier,R> combiner)
在顺序模式下,
supplier
用于创建可变结果容器,然后按顺序应用值。在并行模式中,将创建多个可变结果容器并用值填充它们,然后使用combiner
函数将其合并。没有Vavr等效项。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。