相关疑难解决方法(0)

如何使流减少线程安全?

Java 流 API 提供了一种通用.reduce(identity, accumulator)方法。

从 javadocs 中可以清楚地看出累加器应该是一个无状态函数。

但是,我有一个关于identity对象的问题,即它应该是线程安全的吗?

假设 anidentity是一个 java 对象,并且 anaccumulator以修改不是原子的方式修改该对象,例如accumulator查看identity's状态,然后决定如何准确地修改它的内部状态。很明显,可能会同时运行多个 reduce 操作。在这种情况下,会出现几个问题:

  • 这个减少操作应该在identity对象范围内是原子的吗?
  • 仅仅让identity对象不可变并在每次减少时返回一个新实例就足够了吗?

java multithreading java-stream

17
推荐指数
2
解决办法
415
查看次数

在Stream reduce方法中,对于sum,标识总是0,对于乘法,1必须是1?

我继续学习java 8.

我发现了有趣的行为:

让我们看看代码示例:

// identity value and accumulator and combiner
        Integer summaryAge = Person.getPersons().stream()
                //.parallel()  //will return surprising result
                .reduce(1, (intermediateResult, p) -> intermediateResult + p.age,
                        (ir1, ir2) -> ir1 + ir2);
        System.out.println(summaryAge);
Run Code Online (Sandbox Code Playgroud)

和模型类:

public class Person {

    String name;

    Integer age;
    ///...

    public static Collection<Person> getPersons() {
        List<Person> persons = new ArrayList<>();
        persons.add(new Person("Vasya", 12));
        persons.add(new Person("Petya", 32));
        persons.add(new Person("Serj", 10));
        persons.add(new Person("Onotole", 18));
        return persons;
   }
}
Run Code Online (Sandbox Code Playgroud)

12 + 32 + 10 + 18 = 72
对于序列流,此代码始终返回73(72 …

java reduce java-8 java-stream

13
推荐指数
3
解决办法
6357
查看次数

为什么标识值必须是 Stream.reduce 中组合器函数的标识?

我正在学习Java 8,在包摘要的Reduction操作部分中java.util.stream,它说:

更正式地说,标识值必须是组合器函数的标识。这意味着对于所有 u,combiner.apply(identity, u) 等于 u。此外,组合器函数必须是关联的,并且必须与累加器函数兼容:对于所有 u 和 t,combiner.apply(u,accumulator.apply(identity, t)) 必须是 equals() 到accumulator.apply(u, t)。

我不明白为什么标识值必须是组合器函数的标识。我认为“组合器函数必须是关联的并且必须是兼容的”足以产生相同的结果,无论流是串行还是并行。

例如,我有一个包含四个元素的流e1, e2, e3, e4。如果是串行流,则结果为identityac e1ac e2ac e3ac e4(ac表示累加器函数)。如果是并行流,则四个元素可以分成两部分,[e1, e2][e3, e4],所以结果是 ( identityac e1ac e2) co ( identityac e3ac e4)。

如果给定“组合器函数是关联的并且与累加器函数兼容”,我们可以推断identityac e1ac e2ac e3ac e4等于“( identityac e1ac e2) co ( …

java java-8 java-stream

5
推荐指数
1
解决办法
461
查看次数

Stream reduce vs Stream.parallel.reduce()

我试图理解为什么这个例子的结果总是如此,这是我的例子:

 String s1 = Arrays.asList("A", "E", "I", "O", "U").stream()
                .reduce("", String::concat);
 String s2 = Arrays.asList("A", "E", "I", "O", "U").parallelStream()
                .reduce("", String::concat);

System.out.println(s1.equals(s2));
Run Code Online (Sandbox Code Playgroud)

这总是打印true,我所知道的是使用 parallelStream 我们无法预测结果有人可以解释为什么吗?

java collections reduce java-8 java-stream

4
推荐指数
1
解决办法
372
查看次数

为什么Combiner不影响输出?

以下代码输出始终为24.

public static void main(String[] args) throws InterruptedException {
    List<String> list = new ArrayList<String>();
    list.add("java");
    list.add("php");
    list.add("python");
    list.add("perl");
    list.add("c");
    list.add("lisp");
    list.add("c#");
    int s = list.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> 0);
    System.out.println(s);
    s = list.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> x - y);
    System.out.println(s);
    s = list.stream().reduce(0, (x, y) -> x + y.length(), (x, y) -> x * y);
    System.out.println(s);

}   
Run Code Online (Sandbox Code Playgroud)

问题是组合器影响我的代码的原因.

java java-8 java-stream

2
推荐指数
1
解决办法
64
查看次数

java IntStream并行reduce

并行运行时 a==b 为何为 false 但与组合器一起使用时却有效?

public class test {

 public static int cal(final int i) {
       return 1;
 }
 
 public static void main(String args[]) {

   int a = IntStream.range(0, 3).reduce(0, (abc, cde) -> abc + cal(cde));
   int b = IntStream.range(0, 3).parallel().reduce(0, (abc, cde) -> abc + cal(cde));
   System.out.println(a == b); // false

   int c = List.of(0, 1, 2).stream().parallel().reduce(0, (abc, cde) -> abc + cal(cde), Integer::sum);
   System.out.println(a == c); // true
  }
}
Run Code Online (Sandbox Code Playgroud)

java parallel-processing stream parallelstream

-3
推荐指数
1
解决办法
70
查看次数