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