了解Java8中的拆分器、收集器和流

了解Java8中的拆分器、收集器和流,java,lambda,java-8,spliterator,Java,Lambda,Java 8,Spliterator,我在理解Java8中的接口时遇到困难,尤其是在与和接口有关的地方。我的问题是,我根本无法理解拆分器和收集器接口,因此,流接口对我来说仍然有些模糊 什么是拆分器和收集器,如何使用它们?如果我愿意编写我自己的拆分器或收集器(在这个过程中可能还有我自己的流),我应该做什么,不应该做什么 我阅读了一些分散在网络上的示例,但由于这里的所有内容都是新的,可能会发生更改,因此示例和教程仍然非常稀少。Spliterator基本上是指“可拆分迭代器” 单个线程可以遍历/处理整个拆分器本身,但拆分器还有一个方法tr

我在理解Java8中的接口时遇到困难,尤其是在与和接口有关的地方。我的问题是,我根本无法理解
拆分器
收集器
接口,因此,
接口对我来说仍然有些模糊

什么是
拆分器
收集器
,如何使用它们?如果我愿意编写我自己的
拆分器
收集器
(在这个过程中可能还有我自己的
),我应该做什么,不应该做什么


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

Spliterator
基本上是指“可拆分迭代器”

单个线程可以遍历/处理整个拆分器本身,但拆分器还有一个方法
trySplit()
,该方法将“拆分”一个部分供其他人(通常是另一个线程)处理,从而使当前拆分器的工作量减少

Collector
reduce
函数(map-reduce-fame)的规范与初始值以及组合两个结果的函数(从而使来自分离工作流的结果能够组合在一起)结合起来

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

见:


几乎可以肯定,作为用户,您永远不必处理
拆分器
;只有当您自己编写
集合
类型并且打算优化这些类型上的并行操作时,才有必要使用它

值得一提的是,
Spliterator
是一种对集合元素进行操作的方法,可以很容易地分割集合的一部分,例如,因为您正在并行化,希望一个线程处理集合的一部分,一个线程处理另一部分,等等

实际上,您也不应该将
Stream
类型的值保存到变量中<代码>流有点像一个迭代器,因为它是一个一次性使用的对象,您几乎总是在流畅的链中使用它,如Javadoc示例中所示:

int sum = widgets.stream()
                  .filter(w -> w.getColor() == RED)
                  .mapToInt(w -> w.getWeight())
                  .sum();
Collector
是“reduce”操作的最通用、最抽象的版本,即la-map/reduce;特别是,它需要支持并行化和终结步骤。
收集器的示例包括:

  • 求和,例如
    收集器。减少(0,(x,y)->x+y)
  • StringBuilder追加,例如,
    Collector.of(StringBuilder::new,StringBuilder::append,StringBuilder::append,StringBuilder::toString)

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

 // 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));
//将名称累积到列表中
List List=people.stream().map(Person::getName).collect(Collectors.toList());
//将名称累积到树集合中
Set Set=people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
//将元素转换为字符串并连接它们,用逗号分隔
String joined=things.stream()
.map(对象::toString)
.collect(收集器。连接(“,”);
//计算员工工资总额
int total=employees.stream()
.collect(Collectors.summingit(Employee::getSalary));
//按部门分组的员工
地图分册
=employees.stream()
.collect(Collectors.groupingBy(雇员::getDepartment));
//按部门计算工资总额
地图总览部
=employees.stream()
.collect(收集器)groupingBy(员工::getDepartment,
催收员(summingit(Employee::getSalary));
//将学生分为及格和不及格
映射传递失败=
学生们。stream()
.collect(收集器.partitionby(s->s.getGrade()>=PASS_THRESHOLD));
接口-是的核心功能

界面中显示了默认方法和默认方法。这些方法通过调用
Spliterator()
,使用Spliterator:

。。。
默认流(){
返回StreamSupport.stream(spliterator(),false);
}
默认流parallelStream(){
返回StreamSupport.stream(spliterator(),true);
}
...
Spliterator是一个内部迭代器,它将流分解为更小的部分。这些较小的零件可以并行处理

在其他方法中,有两种最重要的方法可以理解拆分器:

  • 与不同,它尝试使用下一个元素执行操作。 如果操作成功执行,则该方法返回
    true
    。否则,返回
    false
    ——这意味着缺少元素或流的结尾

  • 此方法允许根据一个或另一个标准(文件大小、行数等)将一组数据拆分为多个较小的数据集


拆分器还提供了一种方式来流式处理一个不是集合的Iterable。我的意思是“一个reduce操作,在map/reduce这个术语的意义上”是
收集器。一个旧的beta版本的方法被删除了,或者我遗漏了什么?为了完整性,
(x,y)->x+y
可以写成
Integer::sum
。呃,不,对不起,它是Collector.of,而不是Collector.of。如果你能解释一下你的每个收集器的功能,你的收集器示例会更有用。这并不能回答Op的问题,此外,您的帖子没有任何解释或描述。')如果操作成功执行。')您应该
...

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

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

...