美文网首页
JAVA 8 收集器 使用

JAVA 8 收集器 使用

作者: Snow_DZG | 来源:发表于2016-12-21 11:54 被阅读793次

    JAVA 8 收集器(Collectors) 使用

    收集器功能:1.将流元素归约和汇总 2.元素分组 3.元素分区
    都是 import static java.util.stream.Collectors.*; 前提下

    一、归约和汇总

    1. 查找最大最小值
    maxBy(Comparator)
    minBy(Comparator)
    
    2. 汇总
    求和:
    summingInt(XX::getX)
    summingLong(XX::getX)
    summingDouble(XX::getX)
    求平均值:
    averagingInt(XX::getX)
    averagingDouble(XX::getX)
    averagingLong(XX::getX)
    综合方法,和,平均,最大最小全求出来:
    summarizingInt(XX:getX)
    summarizingDouble(XX:getX)
    summarizingLong(XX:getX)
    
    3. 连接字符串
    joining()  --内部使用StringBuffer拼接
    joining(", ")  --可以添加参数,用什么隔开
    
    4. 广义的归约汇总
    reducing(M,N,W) 需要3个参数 
    
    M   ->  初始值
    N   ->  XX::getX
    W   ->  一个lamda转换函数
    
    reducing(W) 可以一个参数
    
    W   ->  一个Lambda转换函数
    

    二、分组

    Collectors.groupingBy()
    
    1.简单分组
    Collectors.groupingBy(W)  W为一个Lambda
    
    public enum Level { LOW, NORMAL, HIGH };
    Map<Integer, List<Transaction>> maps = trans.parallelStream().collect(groupingBy(Transaction::getValue));
    
    //返回的是Key
    Map<Level, List<Transaction>> maps2 = trans.parallelStream().collect(groupingBy(t -> {
        if (t.getValue() <= 500)
            return Level.LOW;
        else if (t.getValue() <= 1000)
            return Level.NORMAL;
        else
            return Level.HIGH;
    }));
    
    2.多级分组

    多级就是类似按照这一级规则分完组,继续按照下个规则继续分组,将内存传递给外层

    即为groupingBy套用groupingBy
    Collectors.groupingBy(W, groupingBy(M))  W为一个分类函数 M可以为任何类型
    
    Map<Integer, Map<Level, List<Transaction>>> maps3 = trans.parallelStream()
        .collect(groupingBy(Transaction::getYear, groupingBy(t -> {
            if (t.getValue() <= 500)
                return Level.LOW;
            else if (t.getValue() <= 1000)
                return Level.NORMAL;
            else
                return Level.HIGH;
        })));
    
    3.按子组收集数据
    传递给groupingBy的第二个收集器可以是==任何类型==
    普通的单函数groupingBy(f) 实际上为 groupingBy(f, toList())
    Map<Integer, Optional<T>> maps4 = trans.stream().collect(groupingBy(T::getYear,
        maxBy(Comparator.comparingInt(T::getValue))));
    
    3.1 把收集器结果转换为另一种类型
    Collectors.collectingAndThen(W,M) 返回一个收集器
    W:要转换的收集器 M:转换函数
    
    Map<Integer, Transaction> maps5 = trans.stream().collect(groupingBy(Transaction::getYear,
        collectingAndThen(maxBy(comparing(Transaction::getValue)), Optional::get)));
    
    3.2 于groupingBy联合使用的其他收集器
    Collectors.mapping(W,M) 返回一个收集器
    W:转换函数 M:收集函数
    
    这里是先将值映射为Level,将生成的Level流传给toSet,然后返回:
    
    Map<Integer, Set<Level>> maps7 = trans.stream()
        .collect(groupingBy(Transaction::getYear, Collectors.mapping(t -> {
            if (t.getValue() <= 500)
                return Level.LOW;
            else if (t.getValue() <= 1000)
                return Level.NORMAL;
            else
                return Level.HIGH;
        }, toSet())));
        
    Map<Integer, Set<Level>> maps7 = trans.stream()
        .collect(groupingBy(Transaction::getYear, Collectors.mapping(t -> {
            if (t.getValue() <= 500)
                return Level.LOW;
            else if (t.getValue() <= 1000)
                return Level.NORMAL;
            else
                return Level.HIGH;
        }, Collectors.toCollection(HashSet::new))));
        
    Collectors.toCollection(HashSet::new) 可以控制其生成的流的类型
    

    三、分区

    1. 分区
    Collectors.partitioningBy(W)  W必须为返回boolean值的函数
    Collectors.partitioningBy(W,M)  W必须为返回boolean值的函数 M为收集器
    
    直接按照某boolean值分区 true|false
    Map<Boolean, List<Transaction>> map1 = trans.stream().collect(Collectors.partitioningBy(Transaction::getIsOk));
    
    可以添加收集器参数
    Map<Boolean, Map<Integer, List<Transaction>>> map2 = trans.stream()
        .collect(Collectors.partitioningBy(Transaction::getIsOk, groupingBy(Transaction::getYear)));
    
    可以使用collectingAndThen来完成连续收集功能
    Map<Boolean, Transaction> map3 = trans.stream().collect(Collectors.partitioningBy(Transaction::getIsOk,
        collectingAndThen(maxBy(Comparator.comparing(Transaction::getValue)), Optional::get)));
    
    2.按照质数非质数分区
    private boolean isPrime(int num) {
        int num2 = (int) Math.sqrt((double) num);
        return IntStream.rangeClosed(2, num2).noneMatch(t -> num % t == 0);
    }
    
    private  Map<Boolean, List<Integer>> getNum(int n) {
        return IntStream.rangeClosed(2, n).boxed().collect(Collectors.partitioningBy(t -> isPrime(t)));
    }
    
    Map<Boolean, List<Integer>> map4 = getNum(N);
    

    相关文章

      网友评论

          本文标题:JAVA 8 收集器 使用

          本文链接:https://www.haomeiwen.com/subject/tmlqvttx.html