了解Java 8中的Spliterator,Collector和Stream
我无法理解Java 8中的Stream
接口,特别是与Spliterator
和Collector
接口有关的接口。 我的问题是,我简直无法理解Spliterator
和Collector
接口,结果Stream
接口对我来说仍然有些模糊。
Spliterator
和Collector
究竟是什么,我怎样才能使用它们? 如果我愿意写我自己的Spliterator
或Collector
(也许是我自己的Stream
在这个过程中),我该怎么做,而不是做什么?
我阅读了一些散布在networking上的例子,但由于这里的一切都是新的,可能会有所变化,示例和教程仍然非常稀less。
你几乎可以肯定不需要把Spliterator
作为一个用户来处理。 只有在您自己编写Collection
types时才有必要,并且还打算优化它们的并行操作。
对于什么是值得的, Spliterator
是一种对集合中的元素进行操作的方式,它可以很容易地分割集合的一部分,例如,因为你正在并行化并希望一个线程在集合的一部分上工作,另一部分工作的一个线程等
你基本上不应该将Stream
types的值保存到variables中。 Stream
就像一个Iterator
,因为它是一次性使用的对象,你几乎总是在一个stream畅的链中使用,就像在Javadoc的例子中一样:
int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight()) .sum();
Collector
是“减less”操作的最普遍的,抽象可能的版本。 特别是需要支持并行化和定稿的步骤。 Collector
的例子包括:
- 求和,例如
Collectors.reducing(0, (x, y) -> x + y)
- StringBuilder追加,例如
Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString)
Spliterator
基本上是指“可拆分的迭代器”。
单线程可以遍历/处理整个Spliterator本身,但Spliterator也有一个方法trySplit()
,它将为另一个线程(通常是另一个线程)“分离”一个部分进行处理,从而使当前分割器的工作量减less。
Collector
结合了reduce
function(map-reduce fame)的规格,初始值和结合两个结果的值(因此可以将Spliterated工作stream的结果结合起来)。
例如,最基本的收集器将有一个初始值为0,将一个整数添加到现有的结果,并将结合两个结果通过添加它们。 这样总结了一个分裂的整数stream。
看到:
-
Spliterator.trySplit()
-
Collector<T,A,R>
以下是使用预定义收集器执行常见的可变减less任务的示例:
// 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));
作为一个初学者,熟悉使用传统迭代器的google guava中的函数式编程。 检查对象被过滤,转换和收集的方式。 然后移动到Java 8。