chi*_*tiz 5 java binary-operators java-8
我目前正在阅读O'reilly Java 8 Lambdas是一本非常好的书.我遇到过这样的例子.
我有一个
private final BiFunction<StringBuilder,String,StringBuilder>accumulator=
(builder,name)->{if(builder.length()>0)builder.append(",");builder.append("Mister:").append(name);return builder;};
final Stream<String>stringStream = Stream.of("John Lennon","Paul Mccartney"
,"George Harrison","Ringo Starr");
final StringBuilder reduce = stringStream
.filter(a->a!=null)
.reduce(new StringBuilder(),accumulator,(left,right)->left.append(right));
System.out.println(reduce);
System.out.println(reduce.length());
Run Code Online (Sandbox Code Playgroud)
这产生了正确的输出.
Mister:John Lennon,Mister:Paul Mccartney,Mister:George Harrison,Mister:Ringo Starr
我的问题被认为是reduce最后一个参数的方法BinaryOperator
我的问题是这个参数用于哪个?如果我改变
.reduce(new StringBuilder(),accumulator,(left,right)->new StringBuilder());
Run Code Online (Sandbox Code Playgroud)
如果我通过,NULL那么输出是相同的,然后返回NPE.
这个参数用于什么?
UPDATE
为什么如果我运行它parallelStream我收到不同的结果?
第一次运行.
returned StringBuilder length = 420
Run Code Online (Sandbox Code Playgroud)
第二轮
returned StringBuilder length = 546
Run Code Online (Sandbox Code Playgroud)
第三次运行
returned StringBuilder length = 348
Run Code Online (Sandbox Code Playgroud)
等等?为什么这个...不应该在每次迭代时返回所有值?
任何帮助都非常感激.
谢谢.
nos*_*sid 14
reduce接口中的方法Stream被重载.具有三个参数的方法的参数是:
的combiner支持的并行执行.显然,它不用于顺序流.但是,没有这样的保证.如果您将流更改为并行流,我猜您会看到不同之处:
Stream<String>stringStream = Stream.of(
"John Lennon", "Paul Mccartney", "George Harrison", "Ringo Starr")
.parallel();
Run Code Online (Sandbox Code Playgroud)
下面是一个示例,说明如何将combiner顺序缩减转换为缩减,支持并行执行.有一个带有四个Strings 的流,acc用作缩写accumulator.apply.然后,减少的结果可以计算如下:
acc(acc(acc(acc(identity, "one"), "two"), "three"), "four");
Run Code Online (Sandbox Code Playgroud)
通过兼容combiner,可以将上述表达式转换为以下表达式.现在可以在不同的线程中执行两个子表达式.
combiner.apply(
acc(acc(identity, "one"), "two"),
acc(acc(identity, "three"), "four"));
Run Code Online (Sandbox Code Playgroud)
关于你的第二个问题,我使用简化accumulator来解释问题:
BiFunction<StringBuilder,String,StringBuilder> accumulator =
(builder,name) -> builder.append(name);
Run Code Online (Sandbox Code Playgroud)
根据Javadoc for Stream :: reduce,accumulator它必须是关联的.在这种情况下,这意味着,以下两个表达式返回相同的结果:
acc(acc(acc(identity, "one"), "two"), "three")
acc(acc(identity, "one"), acc(acc(identity, "two"), "three"))
Run Code Online (Sandbox Code Playgroud)
对于上述情况,情况并非如此accumulator.问题是,您正在改变引用的对象identity.这对于reduce手术来说是一个坏主意.以下是两个可行的替代实现:
// identity = ""
BiFunction<String,String,String> accumulator = String::concat;
// identity = null
BiFunction<StringBuilder,String,StringBuilder> accumulator =
(builder,name) -> builder == null
? new StringBulder(name) : builder.append(name);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8117 次 |
| 最近记录: |