了解Java 8中的Spliterator,Collector和Stream

我无法理解Java 8中的Stream接口,特别是与SpliteratorCollector接口有关的接口。 我的问题是,我简直无法理解SpliteratorCollector接口,结果Stream接口对我来说仍然有些模糊。

SpliteratorCollector究竟是什么,我怎样才能使用它们? 如果我愿意写我自己的SpliteratorCollector (也许是我自己的Stream在这个过程中),我该怎么做,而不是做什么?

我阅读了一些散布在networking上的例子,但由于这里的一切都是新的,可能会有所变化,示例和教程仍然非常稀less。

你几乎可以肯定不需要把Spliterator作为一个用户来处理。 只有在您自己编写Collectiontypes时才有必要,并且打算优化它们的并行操作。

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

你基本上不应该将Streamtypes的值保存到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结合了reducefunction(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。

    Interesting Posts