用流收集数据

  • 找出流中最大和最小元素
List<Dish> dishes = Arrays.asList(new Dish(), new Dish(), new Dish());
        Dish max = dishes.stream().collect(
            Collectors.maxBy(
                Comparator.comparing(Dish::getName))).get();
        Dish min = dishes.stream().collect(
            Collectors.minBy(
                Comparator.comparing(Dish::getName))).get();
        Dish mmin = dishes.stream().min(Comparator.comparing(Dish::getName)).get();
        Dish mmax = dishes.stream().max(Comparator.comparing(Dish::getName)).get();
  • 汇总
     //汇总
        Integer categaries = dishes.stream().collect(Collectors.summingInt(Dish::getCategary));
        //summarizingInt 是一个工厂  IntSummaryStatistics返回 max min count sum
        IntSummaryStatistics summaryStatistics = dishes.stream().collect(Collectors.summarizingInt(Dish::getCategary));
        summaryStatistics.getMax();
        summaryStatistics.getMin();
        summaryStatistics.getSum();
        summaryStatistics.getAverage();
        summaryStatistics.getCount();
  • 字符串连接
    joining工厂方法返回的收集器会把对流中每一个对象应用tostring方法得到的字符串连接成一个新的字符串
 //字符串操作
        List<String> strings = Arrays.asList("hello", "join", "world");
        String s = strings.stream().collect(Collectors.joining());
        String collect = strings.stream().collect(Collectors.joining(","));
  • 分组
    一个常见的数据库操作是根据一个或者多个属性对集合中的项目进行分组。
 //按照菜肴类型分组
   Map<String, List<Dish>> typeMaps = dishes.stream().collect(Collectors.groupingBy(Dish::getType));

groupingBy接收一个Function,这个function就是分组函数,按照我们指定的规则进行分组。这个分组函数可以是方法引用也可以是一段lambda表达式。

  • 多级分组
//多级分组 先根据类型分组,分组完成之后再按照名称分组
        Map<String, Map<String, List<Dish>>> groupMaps = dishes.stream().collect(
            Collectors.groupingBy(dish -> dish.getType(),
                Collectors.groupingBy(dish -> dish.getName())));

groupingBy(function,collector)也就是说groupingBy是可以再接收一个collector,这个collector当然可以再次进行分组。

  • 分区
    分区的好处在于保留了分区函数返回true和false的两套流元素列表。
     //分区
        Map<Boolean, List<Dish>> partionMap = dishes.stream().collect(
            Collectors.partitioningBy(dish -> dish.getType().equals("meat")));
        //分区多级函数
        Map<Boolean, Optional<Dish>> meat = dishes.stream().collect(
            Collectors.partitioningBy(dish -> dish.getType().equals("meat"),
                Collectors.maxBy(Comparator.comparing(Dish::getCategary))));

实际工作中很少用到。

收集器接口
    public interface Collector<T,A,R> {
        Supplier<A> supplier();
        BiConsumer<A,R> accumulator();
        Function<A,R> finisher();
        BinaryOperator<A> combiner();
        Set<Characteristics> characteristics();
    }
  • T 是流中要收集的项目的泛型
  • A是累加器的类型,累加器实在收集过程中用于累计部分结果的对象
  • R 是收集操作得到的对象

理解collector接口申明的方法

  • 建立新的结果容器: supplier
    supplier方法必须返回一个结果为空的Supplier,也就是一个无参函数,在调用它是会返回一个空的累加器实例。
      public Supplier<List<T>> supplier() {
            return ()->new ArrayList<T>();
      } 
  • 将元素添加到结果容器: accumulator
    accumulator方法会返回执行规约操作的函数
      public BiComsumer<List<T>,T> accumulator() {
            return (list,item)->list.add(item);
      }
  • 对结果容器应用最终转换:finisher
    在遍历完流之后,finisher方法必须返回在累积过程的最后要调用的一个函数,以便将累加器对象转换为整个集合操作的最终结果。
    public  Function<List<T>,List<T>> finisher() {
        return Function.identity();
    }
  • 合并两个结果容器: combiner
    combiner返回一个供规约操作使用的函数,它定义了对流的各个子部分进行并行处理,各个子部分规约所得的累加器要如何合并。
      public BinaryOperator<List<T>> combiner() {
            return (list1,list2)->{
                    list1.addAll(list2);
                    return list1;
            }
      }
  • characteristics
    characteristics 会返回一个不可变的characteristics集合,它定义了收集器的行为。
    unordered 规约结果不接受流中项目的遍历和累积顺序的影响
    concurrent 可以多线程同时调用
    indentity_finish 表明是一个恒等函数
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 收集器简介 Collector 函数式编程相对于指令式编程的一个主要优势:你只需要指出希望的结果“做什么”,而不用...
    浔它芉咟渡阅读 4,251评论 0 4
  • 收集器简介 汇总 并行流 欢迎访问本人博客查看原文:http://wangnan.tech 收集器简介 对流调用c...
    GhostStories阅读 5,379评论 1 7
  • 用流收集数据 汇总 查找最大值和最小值 连接字符串 广义的归约汇总 reducing需要说那个参数: 1.起始值 ...
    罗志贇阅读 4,155评论 0 51
  • 归约和总结 分组 分区 收集器接口 可以不用实现Collector进行自定义收集
    上海马超23阅读 2,299评论 0 0
  • 第一章:酒病解药 沈家后院,叽叽喳喳,三五只麻雀扑腾着翅膀乱叫着。 弗子西,也终于睡眼朦胧地从睡梦中醒了过来,他迷...
    庄严居士阅读 2,870评论 3 4

友情链接更多精彩内容