方法 | 描述 |
---|---|
collect(Collector c) | 将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法 |
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)。但是Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
方法 | 返回类型 | 作用 |
---|---|---|
toList | List | 把流中元素收集到List |
Listemps=list.stream().collect(Collectors.toList()); | ||
toSet | Set | 把流中元素收集到Set |
Setemps=list.stream().collect(Collectors.toSet()); | ||
toCollection | Collection | 把流中元素收集到创建的集合 |
Collectionemps=list.stream().collect(Collectors.toCollection(ArrayList::new)); | ||
counting | Long | 计算流中元素的个数 |
longcount=list.stream().collect(Collectors.counting()); | ||
summingInt | Integer | 对流中元素的整数属性求和 |
inttotal=list.stream().collect(Collectors.summingInt(Employee::getSalary)); | ||
averagingInt | Double | 计算流中元素Integer属性的平均值 |
doubleavg=list.stream().collect(Collectors.averagingInt(Employee::getSalary)); | ||
summarizingInt | IntSummaryStatistics | 收集流中Integer属性的统计值。如:平均值 |
IntSummaryStatisticsiss=list.stream().collect(Collectors.summarizingInt(Employee::getSalary)); | ||
joining | String | 连接流中每个字符串 |
Stringstr=list.stream().map(Employee::getName).collect(Collectors.joining()); | ||
maxBy | Optional | 根据比较器选择最大值 |
Optionalmax=list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary))); | ||
minBy | Optional | 根据比较器选择最小值 |
Optionalmin=list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary))); | ||
reducing | 归约产生的类型 | 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值 |
inttotal=list.stream().collect(Collectors.reducing(0,Employee::getSalar,Integer::sum)); | ||
collectingAndThen | 转换函数返回的类型 | 包裹另一个收集器,对其结果转换函数 |
inthow=list.stream().collect(Collectors.collectingAndThen(Collectors.toList(),List::size)); | ||
groupingBy | Map> | 根据某属性值对流分组,属性为K,结果为V |
Map |
测试代码
TestCollectors.java
package java8.collectors;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.junit.Test;
import java8.collectors.Person.Status;
/**
* @author 微信公众号:JavaWeb架构师
* @version 创建时间:2017年12月29日 上午10:32:00
*/
public class TestCollectors {
private List<Integer> listInteger = Arrays.asList(1,2,3,4,80,-1,-2,-3,-4,-5,0,50,10,-60);
private List<Person> listPerson = Arrays.asList(
new Person(Person.Status.VACATION, 18,"冯强"),
new Person(Person.Status.WORK, 16,"周杰伦"),
new Person(Person.Status.REST, 20,"廖周涛"),
new Person(Person.Status.WORK, 25,"鹿晗"),
new Person(Person.Status.VACATION, 25,"吴亦凡")
);
/**
* 1.收集
* collect(Collector c):
* 将流转换为其他形式。接收一个Collector接口的实现,
* 用于给Stream中元素做汇总的方法
*/
/**
* <R,A> R collect(Collector<? super T,A,R> collector):
* 使用Collector对此流的元素执行mutable reduction Collector 。
* A Collector将用作参数的函数封装到collect(Supplier, BiConsumer, BiConsumer) ,允许重用集合策略和组合收集操作(如多级分组或分区)。
* 如果流是并行的,并且Collector是concurrent ,并且流是无序的或收集器是unordered ,
* 则将执行并发的减少(有关并发减少的细节,请参阅Collector )。
* 这是一个terminal operation 。
* 当并行执行时,可以实例化,填充和合并多个中间结果,以便保持可变数据结构的隔离。
* 因此,即使与非线程安全的数据结构(例如ArrayList )并行执行,并行还原也不需要额外的同步。
* 参数类型
* R - 结果的类型
* A - 中间累积类型的 Collector
* 参数
* collector - Collector减少的Collector
* 结果
* 减少的结果
*/
/**
* Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)。
* 但是Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例。
*/
// 1.把结果转换成List(类似的可以收集到Set、Map)
@Test
public void test1() {
/**
* public static <T> Collector<T,?,List<T>> :
* toList()返回一个Collector ,它将输入元素List到一个新的List 。
* List返回的类型,可变性,可序列化或线程安全性没有List ;
* 如果需要对返回的List进行更多的控制,请使用toCollection(Supplier) 。
* 参数类型
* T - 输入元素的类型
* 结果
* 一个 Collector ,它将所有输入元素收集到一个 List中,按照顺序
*/
// 把其中大于0的元素返回到一个List中去
List<Integer> list = listInteger.stream()
.filter((e) -> e > 0)
.collect(Collectors.toList());
// 遍历
list.forEach(System.out::println);
}
// 2.把结果转换成Collection(可以指定到具体的List、Set、Map)
@Test
public void test2() {
// 收集到LinkedList中去
LinkedList<Double> collect = listInteger.stream()
.map((e) -> e + 1.1)
.collect(Collectors.toCollection(LinkedList::new));
collect.forEach(System.out::println);
}
// 3.对结果求平均值、求总和、……
@Test
public void test3() {
// 元素总数
Long count = listInteger.stream().collect(Collectors.counting());
System.out.println("元素总数是:" + count);
// 平均值
Double average = listInteger.stream().collect(Collectors.averagingDouble(Integer::intValue));
System.out.println("平均值是:" + average);
// 求和
Double sum = listInteger.stream().collect(Collectors.summingDouble(Integer::intValue));
System.out.println("总和是:" + sum);
// 最大值
Optional<Integer> maxValue = listInteger.stream().collect(Collectors.maxBy(Integer::compareTo));
System.out.println("最大值是:" + maxValue.get());
// 通过summarizingDouble获取总和、元素个数、平均值、最大最小值
DoubleSummaryStatistics summaryStatistics = listInteger.stream().collect(Collectors.summarizingDouble(Integer::intValue));
System.out.println(summaryStatistics.getCount());
System.out.println(summaryStatistics.getAverage());
System.out.println(summaryStatistics.getSum());
System.out.println(summaryStatistics.getMax());
System.out.println(summaryStatistics.getMin());
}
// 4.分组(单分组、多分组)
@Test
public void test4() {
/**
* 参数(Function):分组标准Function
*/
// 单按状态分组
Map<Status, List<Person>> statusPersons = listPerson.stream().
collect(Collectors.groupingBy(Person::getStatus));
System.out.println(statusPersons);
/**
* 参数(Function,Collector):当前分组Function,再分组Collector
*/
// 多分组:先按状态,同状态再按年龄分
Map<Status, Map<String, List<Person>>> mulPerson = listPerson.stream().collect(Collectors.groupingBy(Person::getStatus,
Collectors.groupingBy((e) -> {
if( e.getAge() < 18 ) {
return "少年";
} else if(e.getAge() >= 18 && e.getAge() < 50) {
return "青年";
} else {
return "老年";
}
})));
System.out.println(mulPerson);
}
// 5.分区(true、false两个区域)
@Test
public void test5() {
// 大于等于20岁的一个分区,小于20岁的一个分区
Map<Boolean, List<Person>> partiAge = listPerson.stream().collect(Collectors.partitioningBy((e) -> e.getAge() > 20));
System.out.println(partiAge);
}
}
其它
- 源码下载
关注下方公众号,回复:Java8.code
欢迎加入交流群:451826376
更多信息:www.itcourse.top