Java8新特性-011-Stream收集-终止操作

方法描述
collect(Collector c)将流转换为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法

Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)。但是Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

方法返回类型作用
toListList把流中元素收集到List
Listemps=list.stream().collect(Collectors.toList());
toSetSet把流中元素收集到Set
Setemps=list.stream().collect(Collectors.toSet());
toCollectionCollection把流中元素收集到创建的集合
Collectionemps=list.stream().collect(Collectors.toCollection(ArrayList::new));
countingLong计算流中元素的个数
longcount=list.stream().collect(Collectors.counting());
summingIntInteger对流中元素的整数属性求和
inttotal=list.stream().collect(Collectors.summingInt(Employee::getSalary));
averagingIntDouble计算流中元素Integer属性的平均值
doubleavg=list.stream().collect(Collectors.averagingInt(Employee::getSalary));
summarizingIntIntSummaryStatistics收集流中Integer属性的统计值。如:平均值
IntSummaryStatisticsiss=list.stream().collect(Collectors.summarizingInt(Employee::getSalary));
joiningString连接流中每个字符串
Stringstr=list.stream().map(Employee::getName).collect(Collectors.joining());
maxByOptional根据比较器选择最大值
Optionalmax=list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary)));
minByOptional根据比较器选择最小值
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));
groupingByMap>根据某属性值对流分组,属性为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);
    }
}

微信公众号:JavaWeb架构师


其它

  • 源码下载
关注下方公众号,回复:Java8.code

完整教程PDF版本下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值