了解 Java 8 中的 Spliterator、Collector 和 Stream

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19235606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 15:19:03  来源:igfitidea点击:

Understanding Spliterator, Collector and Stream in Java 8

javalambdajava-8spliterator

提问by Victor Stafusa

I am having trouble understanding the Streaminterface in Java 8, especially where it has to do with the Spliteratorand Collectorinterfaces. My problem is that I simply can't understand Spliteratorand the Collectorinterfaces yet, and as a result, the Streaminterface is still somewhat obscure to me.

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

What exactly is a Spliteratorand a Collector, and how can I use them? If I am willing to write my own Spliteratoror Collector(and probably my own Streamin that process), what should I do and not do?

到底什么是 aSpliterator和 a Collector,我该如何使用它们?如果我愿意写自己的SpliteratorCollector(可能Stream在那个过程中是我自己的),我应该做什么和不做什么?

I read some examples scattered around the web, but since everything here is still new and subject to changes, examples and tutorials are still very sparse.

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

采纳答案by Louis Wasserman

You should almost certainly never have to deal with Spliteratoras a user; it should only be necessary if you're writing Collectiontypes yourself and alsointending to optimize parallelized operations on them.

几乎可以肯定,您永远不必以Spliterator用户的身份进行处理;如果你在写它时,才需要Collection类型的自己,打算并行优化他们的操作。

For what it's worth, a Spliteratoris a way of operating over the elements of a collection in a way that it's easy to split off part of the collection, e.g. because you're parallelizing and want one thread to work on one part of the collection, one thread to work on another part, etc.

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

You should essentially never be saving values of type Streamto a variable, either. Streamis sort of like an Iterator, in that it's a one-time-use object that you'll almost always use in a fluent chain, as in the Javadoc example:

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

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

Collectoris the most generalized, abstract possible version of a "reduce" operation a la map/reduce; in particular, it needs to support parallelization and finalization steps. Examples of Collectors include:

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

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

回答by Thomas W

Spliteratorbasically means "splittable Iterator".

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

Single thread can traverse/process the entire Spliterator itself, but the Spliterator also has a method trySplit()which will "split off" a section for someone else (typically, another thread) to process -- leaving the current spliterator with less work.

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

Collectorcombines the specification of a reducefunction (of map-reduce fame), with an initial value, and a function to combine two results (thus enabling results from Spliterated streams of work, to be combined.)

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

For example, the most basic Collector would have an initial vaue of 0, add an integer onto an existing result, and would 'combine' two results by adding them. Thus summing a spliterated stream of integers.

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

See:

看:

回答by Ajay Kumar

The following are examples of using the predefined collectors to perform common mutable reduction tasks:

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

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

回答by Ajay Kumar

Interface Spliterator- is a core feature of Streams.

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

The stream()and parallelStream()default methods are presented in the Collectioninterface. These methods use the Spliterator through the call to the spliterator():

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

...

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

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

...

Spliterator is an internal iterator that breaks the stream into the smaller parts. These smaller parts can be processed in parallel.

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

Among other methods, there are two most important to understand the Spliterator:

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

  • boolean tryAdvance(Consumer<? super T> action)Unlike the Iterator, it tries to perform the operation with the next element. If operation executed successfully, the method returns true. Otherwise, returns false- that means that there is absence of element or end of the stream.

  • Spliterator<T> trySplit()This method allows to split a set of data into a many smaller sets according to one or another criteria (file size, number of lines, etc).