Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8 reduce BinaryOperator用于什么?_Java_Java 8_Binary Operators - Fatal编程技术网

Java 8 reduce BinaryOperator用于什么?

Java 8 reduce BinaryOperator用于什么?,java,java-8,binary-operators,Java,Java 8,Binary Operators,我目前正在阅读的O'reillyjava8lambdas是一本非常好的书。我遇到了这样一个例子 我有一个 private final BiFunction<StringBuilder,String,StringBuilder>accumulator= (builder,name)->{if(builder.length()>0)builder.append(",");builder.append("Mister:").append(name);return builder

我目前正在阅读的
O'reilly
java8lambdas是一本非常好的书。我遇到了这样一个例子

我有一个

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());
如果我通过
NULL
则返回N.p.E,则输出相同

此参数的用途是什么

更新

为什么在
parallelStream
上运行它会收到不同的结果

第一轮

returned StringBuilder length = 420
第二轮

returned StringBuilder length = 546
第三轮

returned StringBuilder length = 348
等等?为什么这是。。。是否不应在每次迭代时返回所有值

任何帮助都是万分感激的


谢谢。

接口
中的方法
reduce
过载。具有三个参数的方法的参数为:

  • 身份
  • 累加器
  • 组合器
组合器支持并行执行。显然,它不用于连续流。然而,没有这样的保证。如果您将流更改为并行流,我想您会看到不同:

Stream<String>stringStream = Stream.of(
    "John Lennon", "Paul Mccartney", "George Harrison", "Ringo Starr")
    .parallel();
使用兼容的组合器
,可以将上述表达式转换为以下表达式。现在可以在不同的线程中执行这两个子表达式

combiner.apply(
    acc(acc(identity, "one"), "two"),
    acc(acc(identity, "three"), "four"));

关于你的第二个问题,我用一个简化的
累加器
来解释这个问题:

BiFunction<StringBuilder,String,StringBuilder> accumulator =
    (builder,name) -> builder.append(name);
对于上述
累加器
,情况并非如此。问题是,您正在对
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);
//identity=“”
双功能累加器=字符串::concat;
//标识=null
双功能累加器=
(生成器,名称)->builder==null
? 新建StringBulder(名称):builder.append(名称);
基本正确(+1),但我想放大一个特定点

identity
参数到
reduce
必须是一个identity值。如果它是一个对象就可以了,但如果是,它应该是不可变的。如果“身份”对象发生变异,它就不再是身份!有关这一点的更多讨论,请参阅相关问题


看起来这个例子源自Richard Warburton的例子5-19,Java 8 Lambdas,O'Reilly 2014。如果是这样的话,我必须和善良的沃伯顿博士谈谈这件事。

谢谢你,我有一个问题,为什么每次迭代我都会收到不同的结果,我猜是为了并行化。。。为什么这几个结果使用名称代码??请看我编辑的问题。@chiperortiz:我已经更新了关于第二个问题的答案。这个例子真的源于这本书吗?在这种情况下,短语good book似乎有问题。在这本书中,是一个更复杂的示例,仅使用顺序流。我将使用双函数,但我是否应该使用相同的BinaryOperator?类似地,要reduce的BinaryOperator参数必须是关联的。否则,您将并行得到乱七八糟的结果。Richard的示例用于顺序流而不是并行流Stuart,谢谢您的回复…@chiperortiz该示例确实是顺序的,但代码顺序给出正确的结果和并行给出错误的结果是不合适的,尤其是在一本试图解释这些东西的书中。(此外,我怀疑即使是顺序代码也违反了一些限制,幸运的是它恰好给出了正确的结果。)
BiFunction<StringBuilder,String,StringBuilder> accumulator =
    (builder,name) -> builder.append(name);
acc(acc(acc(identity, "one"), "two"), "three")  
acc(acc(identity, "one"), acc(acc(identity, "two"), "three"))
// 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);