Java parallelStream vs.stream.parallel
我一直很好奇Collections.parallelStream和Collections.stream.parallel之间的区别。根据Javadocs,parallelStream尝试返回并行流,而stream.parallel返回并行流。通过我自己的一些测试,我没有发现任何差异。这两种方法的区别在哪里?一个实现比另一个实现更省时吗?谢谢。Collections.parallelStream和Collections.stream.parallel之间没有区别。它们都将在底层拆分器允许的范围内对流进行拆分,并且它们都将使用默认的ForkJoinPool运行,除非已经在另一个ForkJoinPool中运行。即使它们目前的行为相同,也存在差异-至少在它们的文档中,正如您正确指出的那样;据我所知,这可能在未来被利用 目前,parallelStream方法在集合接口中定义为:Java parallelStream vs.stream.parallel,java,java-8,java-stream,Java,Java 8,Java Stream,我一直很好奇Collections.parallelStream和Collections.stream.parallel之间的区别。根据Javadocs,parallelStream尝试返回并行流,而stream.parallel返回并行流。通过我自己的一些测试,我没有发现任何差异。这两种方法的区别在哪里?一个实现比另一个实现更省时吗?谢谢。Collections.parallelStream和Collections.stream.parallel之间没有区别。它们都将在底层拆分器允许的范围内对
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
至少对我来说,这看起来很奇怪
似乎文档应该以某种方式声明,在调用parallelStream之后,没有理由再次调用parallel来强制执行该操作,因为它可能对处理没有用处,甚至是有害的
编辑
对于阅读本文的任何人,也请阅读霍尔格的评论;它涵盖的案例超出了我在回答中所说的范围
class Employee {
String name;
int salary;
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
}
class ParallelStream {
public static void main(String[] args) {
long t1, t2;
List<Employee> eList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
eList.add(new Employee("A", 20000));
eList.add(new Employee("B", 3000));
eList.add(new Employee("C", 15002));
eList.add(new Employee("D", 7856));
eList.add(new Employee("E", 200));
eList.add(new Employee("F", 50000));
}
/***** Here We Are Creating A 'Sequential Stream' & Displaying The Result *****/
t1 = System.currentTimeMillis();
System.out.println("Sequential Stream Count?= " + eList.stream().filter(e -> e.getSalary() > 15000).count());
t2 = System.currentTimeMillis();
System.out.println("Sequential Stream Time Taken?= " + (t2 - t1) + "\n");
/***** Here We Are Creating A 'Parallel Stream' & Displaying The Result *****/
t1 = System.currentTimeMillis();
System.out.println("Parallel Stream Count?= " + eList.parallelStream().filter(e -> e.getSalary() > 15000).count());
t2 = System.currentTimeMillis();
System.out.println("Parallel Stream Time Taken?= " + (t2 - t1));
/***** Here We Are Creating A 'Parallel Stream with Collection.stream.parallel' & Displaying The Result *****/
t1 = System.currentTimeMillis();
System.out.println("stream().parallel() Count?= " + eList.stream().parallel().filter(e -> e.getSalary() > 15000).count());
t2 = System.currentTimeMillis();
System.out.println("stream().parallel() Time Taken?= " + (t2 - t1));
}
}
我不确定,但正如在O/p中所提到的,stream.parallel是parallelStream的1/6
不过,任何专家的建议都是受欢迎的。简短回答:没有区别。长句回答:没有区别。他们只是彼此的别名。我只是找到了一些东西,我不知道这是否代表了他们的不同?请看,很难想象一个场景,在不知道将链接哪些实际操作的情况下,流源拒绝对流进行并行处理是合理的。也许,如果它正在滚动它自己的流API实现,那么,它完全控制调用.parallel时发生的事情……好吧,空集合永远不会从并行处理中受益,但是,因为无论如何都不能保证线程的数量,所以仍然让isParallel返回true是没有害处的。类似地,没有flatMap操作的单例集合上的流永远不会使用第二个线程,尽管如此,isParallel返回true并没有什么害处。这也适用于其底层拆分器在trySplit中返回null的所有流;如果没有排序或平面图之类的东西,不管你是否调用.parallel;它不会有任何效果。只是想一想,如果你有一个不支持任何并行处理的源,那么仍然没有理由使用source.parallelStream.sorted。一旦填充了内部使用的数组,就应该禁止otherOps使用并行处理,因为此时,处理与源完全分离。我觉得这句话源于源代码和流实现之间的交互仍在进行中的一段时间。@Holger有时我实际上没有得到你的答案,但一定要设法找到那些人来修改它们。。。这里的“内部数组”是指将元素从拆分器复制到接收器数组或ArrayList的排序操作,对吗?很抱歉这么晚才提出此问题是的,确切地说,排序所使用的临时存储(无论是否为数组)独立于源集合,因此它可以并行处理,即使源尝试拒绝它。类似地,如果拆分器的trySplit方法返回null,则流实现可以像AbstractSpliterator.trySplit那样转向缓冲策略。实际上,如果流执行此操作而不是AbstractSpliterator,则更有意义……如果单独运行流,可以看到流的时间几乎相同。
class Employee {
String name;
int salary;
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
}
class ParallelStream {
public static void main(String[] args) {
long t1, t2;
List<Employee> eList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
eList.add(new Employee("A", 20000));
eList.add(new Employee("B", 3000));
eList.add(new Employee("C", 15002));
eList.add(new Employee("D", 7856));
eList.add(new Employee("E", 200));
eList.add(new Employee("F", 50000));
}
/***** Here We Are Creating A 'Sequential Stream' & Displaying The Result *****/
t1 = System.currentTimeMillis();
System.out.println("Sequential Stream Count?= " + eList.stream().filter(e -> e.getSalary() > 15000).count());
t2 = System.currentTimeMillis();
System.out.println("Sequential Stream Time Taken?= " + (t2 - t1) + "\n");
/***** Here We Are Creating A 'Parallel Stream' & Displaying The Result *****/
t1 = System.currentTimeMillis();
System.out.println("Parallel Stream Count?= " + eList.parallelStream().filter(e -> e.getSalary() > 15000).count());
t2 = System.currentTimeMillis();
System.out.println("Parallel Stream Time Taken?= " + (t2 - t1));
/***** Here We Are Creating A 'Parallel Stream with Collection.stream.parallel' & Displaying The Result *****/
t1 = System.currentTimeMillis();
System.out.println("stream().parallel() Count?= " + eList.stream().parallel().filter(e -> e.getSalary() > 15000).count());
t2 = System.currentTimeMillis();
System.out.println("stream().parallel() Time Taken?= " + (t2 - t1));
}
}
Sequential Stream Count?= 300
Sequential Stream Time Taken?= 18
Parallel Stream Count?= 300
Parallel Stream Time Taken?= 6
stream().parallel() Count?= 300
stream().parallel() Time Taken?= 1