我已经习惯了在Scala编程,但我必须写一些Java和我试图执行以下斯卡拉相当于片段:
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
。
我对的API无法控制Options
。elems
并不需要一个Stream
。
这是不可能写出来与大家所提供的接口组合。问题是,一个组合需要一种方法来两者结合起来Options
,但没有办法做到这一点。唯一的一点任何人都可以用做Options
实例是一个对添加到它。我不能得到的任何信息了。这大概不能做任何事情非常有用的。
也许这个问题的事实,Java不具备的特征也不是Java接口的性状合适的替代造成的。
在Java习惯的方式来写这仅仅是一个沼泽标准的for循环:
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的是不同的语言。你不应该期望一切都完全类似。如果那样,就没有理由摆在首位存在两种语言。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句