繁体   English   中英

理解 Java 8 中的 Spliterator、Collector 和 Stream

[英]Understanding Spliterator, Collector and Stream in Java 8

我无法理解 Java 8 中的Stream接口,尤其是它与SpliteratorCollector接口有关的地方。 我的问题是我根本无法理解SpliteratorCollector接口,因此, Stream接口对我来说仍然有些模糊。

SpliteratorCollector究竟是什么,我该如何使用它们? 如果我愿意编写自己的SpliteratorCollector (并且可能在该过程中编写我自己的Stream ),我应该做什么和不做什么?

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

作为用户,您几乎肯定永远不必与Spliterator打交道; 如果你正在写它应该只需要Collection自己的类型,并且打算并行优化他们的操作。

就其价值而言, Spliterator是一种对集合元素进行操作的方式,这种方式很容易拆分集合的一部分,例如,因为您正在并行化并希望一个线程处理集合的一部分,一个线程处理另一部分,等等。

您本质上也不应该将Stream类型的值保存到变量中。 Stream有点像一个Iterator ,因为它是一个一次性使用的对象,您几乎总是在流利的链中使用它,如在 Javadoc 示例中所示:

int sum = widgets.stream()
                  .filter(w -> w.getColor() == RED)
                  .mapToInt(w -> w.getWeight())
                  .sum();

Collector是“化简”操作的最通用、最抽象的可能版本,如 map/reduce; 特别是,它需要支持并行化和最终化步骤。 Collector的示例包括:

  • 求和,例如Collectors.reducing(0, (x, y) -> x + y)
  • StringBuilder 追加,例如Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString)

Spliterator基本上意味着“可拆分的迭代器”。

单线程可以遍历/处理整个 Spliterator 本身,但 Spliterator 也有一个trySplit()方法,该方法将“拆分”一部分供其他人(通常是另一个线程)处理——让当前的 spliterator 工作更少。

Collector结合了(map-reduce 名望的) reduce函数的规范、初始值和组合两个结果的函数(从而使来自 Spliterated 工作流的结果能够被组合。)

例如,最基本的收集器的初始值为 0,在现有结果上添加一个整数,并通过添加两个结果来“组合”两个结果。 从而对分割的整数流求和。

见:

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

 // 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));

Interface 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);
}

...

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM