[英]Folding a sequential stream in Java
我习惯在Scala中编程,但是我必须编写一些Java,并且我正在尝试执行以下Scala代码段的等效操作:
trait Options[K, V] {
def add(key: K , value: V): Options[K, V]
}
val options: Options[T, U] = ???
val elems: List[(T, U)] = ???
elems.foldLeft(options) {
case (opts, (key, value)) => opts.add(key, value)
}
即,我的折叠上的元素elems
内部options
,在每个步骤中产生的新实例。
我尝试使用Java的Stream#reduce
:
interface Options<K, V> {
Options<K, V> add(K key, V value);
}
Options<K, V> options = ???
Stream<Tuple2<K, V>> elems = ??? // This is Reactor's Tuple2
elems.reduce(options, (opts, opt) -> opts.add(opt), ???)
我不知道合成器应该是什么,我很难想象它的参数会有什么价值。 我的理解是combiner
将用于组合并行流中并行产生的中间值。 在我的情况下,我根本不关心并行处理elems
。 换句话说,我正在寻找Flux#reduce
的同步和顺序版本。
我无法控制Options
的API。 elems
不需要是Stream
。
使用您提供的界面编写组合器是不可能的。 问题是组合器需要一种方法来组合两个Options
但是没有办法做到这一点。 任何人都可以对Options
实例做的唯一事情就是为它添加一对。 我无法从中得到任何信息。 它可能无法做任何非常有用的事情。
也许这个问题源于Java没有特征,Java接口也不适合替代特征。
写这个的惯用Java方式只是一个标准的for-loop循环:
Options<String, String> options = /*whatever*/;
List<Pair<String, String>> elems = /*whatever*/;
for (Pair<String, String> pair : elems)
{
options = options.add(pair.getKey(), pair.getValue());
}
如果您可以处理您永远无法使用并行流这一事实,则可以利用顺序流永远不会实际使用组合器这一事实。 因此,您可以编写一个Collector
来定义一个只会抛出异常的组合器。
Options<String, String> foo = elems.stream()
.collect(
() -> options,
(opt, pair) -> opt.add(pair.getKey(), pair.getValue()),
(a, b) -> { throw new UnsupportedOperationException(); }
);
如果你真的想使用reduce
,你需要修改你的界面,以暴露一些关于它包含的键值对的信息,或者提供一次添加多个键值对的方法。 例如:
interface Options<K, V>
{
Options<K, V> add(K key, V value);
Options<K, V> add(Options<K, V> otherOptions);
}
Options<String, String> options = /*whatever*/;
List<Pair<String, String>> elems = /*whatever*/;
Options<String, String> foo = elems.stream()
.reduce(
options,
(opt, pair) -> opt.add(pair.getKey(), pair.getValue()),
Options::add
);
我怀疑这是你想听到的,但Scala和Java是不同的语言。 你不应该期望一切都有一个完全平行的。 如果确实如此,那么首先就没有两种语言存在的理由。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.