了解Java 8中的Spliterator,Collector和Stream

Vic*_*usa 135 java lambda java-8 spliterator

我无法理解StreamJava 8中的接口,特别是它SpliteratorCollector接口有关的地方.我的问题是我根本就没有理解SpliteratorCollector接口,并因此在Stream界面依然有些模糊了我.

究竟什么是a Spliterator和a Collector,我该如何使用它们?如果我愿意自己编写SpliteratorCollector(也可能是我自己的编写Stream过程),我应该做什么而不是做什么?

我阅读了一些散布在网络上的例子,但由于这里的所有内容都是新的并且可能会有变化,因此示例和教程仍然非常稀少.

Lou*_*man 137

你几乎肯定不必Spliterator作为用户处理; 只有你Collection自己编写类型并且打算优化它们的并行操作时才应该这样做.

对于它的价值,a Spliterator是一种操作集合元素的方式,它可以很容易地分离集合的一部分,例如,因为你是并行化并希望一个线程在集合的一部分上工作,一个线程在另一个部分上工作,等等.

你本质上永远不应该将类型的值保存Stream到变量中. Stream有点像一个Iterator,因为它是一个一次性使用的对象,你几乎总是在流畅的链中使用,就像在Javadoc示例中一样:

int sum = widgets.stream()
                  .filter(w -> w.getColor() == RED)
                  .mapToInt(w -> w.getWeight())
                  .sum();
Run Code Online (Sandbox Code Playgroud)

Collector是la map/reduce的"reduce"操作的最通用的,抽象的可能版本; 特别是,它需要支持并行化和完成步骤.例子Collector包括:

  • 总结,例如 Collectors.reducing(0, (x, y) -> x + y)
  • StringBuilder附加,例如 Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString)

  • Spliterator还提供了一种流式传输不是Collection的Iterable的方法 (30认同)
  • 我的意思是"减少操作,在某种意义上,术语是指map/reduce" (2认同)
  • 呃,不,对不起,这是Collector.of,而不是Collectors.of. (2认同)
  • 如果您能解释每个收集器的作用,您的收集器示例会更有用。 (2认同)

Tho*_*s W 86

Spliterator 基本上意味着"可拆分的迭代器".

单线程可以遍历/处理整个Spliterator本身,但是Spliterator还有一个方法trySplit()可以"拆分"一个部分供其他人(通常是另一个线程)处理 - 让当前的分裂器工作量减少.

Collector将一个reduce函数(map-reduce fame)的规范与一个初始值和一个值结合起来组合两个结果(从而使得Spliterated工作流的结果能够被组合起来).

例如,最基本的收集器的初始值为0,在现有结果上添加一个整数,并通过添加它们来"组合"两个结果.从而总结了一个分裂的整数流.

看到:


Aja*_*mar 6

以下是使用预定义收集器执行常见的可变减少任务的示例:

 // Accumulate names into a List
 List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());

 // Accumulate names into a TreeSet
 Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));

 // Convert elements to strings and concatenate them, separated by commas
 String joined = things.stream()
                       .map(Object::toString)
                       .collect(Collectors.joining(", "));

 // Compute sum of salaries of employee
 int total = employees.stream()
                      .collect(Collectors.summingInt(Employee::getSalary)));

 // Group employees by department
 Map<Department, List<Employee>> byDept
     = employees.stream()
                .collect(Collectors.groupingBy(Employee::getDepartment));

 // Compute sum of salaries by department
 Map<Department, Integer> totalByDept
     = employees.stream()
                .collect(Collectors.groupingBy(Employee::getDepartment,
                                               Collectors.summingInt(Employee::getSalary)));

 // Partition students into passing and failing
 Map<Boolean, List<Student>> passingFailing =
     students.stream()
             .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
Run Code Online (Sandbox Code Playgroud)

  • 这不能回答 Op 的问题,而且没有对您的帖子进行解释或描述。 (3认同)

小智 5

接口Spliterator- 是Streams的核心功能。

stream()parallelStream()默认的方法都在展示Collection界面。这些方法通过调用来使用 Spliterator spliterator()

...

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

default Stream<E> parallelStream() {
    return StreamSupport.stream(spliterator(), true);
}

...
Run Code Online (Sandbox Code Playgroud)

Spliterator 是一个内部迭代器,它将流分解为更小的部分。这些较小的零件可以并行处理。

在其他方法中,理解 Spliterator 最重要的有两个: