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
顺序缩减转换为缩减,支持并行执行.有一个带有四个String
s 的流,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)