了解 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
Understanding Spliterator, Collector and Stream in Java 8
提问by Victor Stafusa
I am having trouble understanding the Stream
interface in Java 8, especially where it has to do with the Spliterator
and Collector
interfaces. My problem is that I simply can't understand Spliterator
and the Collector
interfaces yet, and as a result, the Stream
interface is still somewhat obscure to me.
我在理解Stream
Java 8 中的接口时遇到了麻烦,尤其是它与Spliterator
和Collector
接口有关的地方。我的问题是我根本无法理解Spliterator
和Collector
接口,因此,Stream
接口对我来说仍然有些模糊。
What exactly is a Spliterator
and a Collector
, and how can I use them? If I am willing to write my own Spliterator
or Collector
(and probably my own Stream
in that process), what should I do and not do?
到底什么是 aSpliterator
和 a Collector
,我该如何使用它们?如果我愿意写自己的Spliterator
或Collector
(可能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 Spliterator
as a user; it should only be necessary if you're writing Collection
types yourself and alsointending to optimize parallelized operations on them.
几乎可以肯定,您永远不必以Spliterator
用户的身份进行处理;如果你在写它时,才需要Collection
类型的自己,还打算并行优化他们的操作。
For what it's worth, a Spliterator
is 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 Stream
to a variable, either. Stream
is 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();
Collector
is 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 Collector
s 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
Spliterator
basically 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 工作更少。
Collector
combines the specification of a reduce
function (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.)
Collector
将reduce
函数(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 Collection
interface. 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 theIterator
, it tries to perform the operation with the next element. If operation executed successfully, the method returnstrue
. Otherwise, returnsfalse
- 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).
boolean tryAdvance(Consumer<? super T> action)
与 不同Iterator
,它尝试使用下一个元素执行操作。如果操作成功执行,则该方法返回true
。否则,返回false
- 这意味着没有元素或流结束。Spliterator<T> trySplit()
此方法允许根据一个或另一个标准(文件大小、行数等)将一组数据拆分为许多较小的集合。