用流收集数据

  • 找出流中最大和最小元素
List 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 strings = Arrays.asList("hello", "join", "world");
        String s = strings.stream().collect(Collectors.joining());
        String collect = strings.stream().collect(Collectors.joining(","));
  • 分组
    一个常见的数据库操作是根据一个或者多个属性对集合中的项目进行分组。
 //按照菜肴类型分组
   Map> typeMaps = dishes.stream().collect(Collectors.groupingBy(Dish::getType));

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

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

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

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

实际工作中很少用到。

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

理解collector接口申明的方法

  • 建立新的结果容器: supplier
    supplier方法必须返回一个结果为空的Supplier,也就是一个无参函数,在调用它是会返回一个空的累加器实例。
      public Supplier> supplier() {
            return ()->new ArrayList();
      } 
  • 将元素添加到结果容器: accumulator
    accumulator方法会返回执行规约操作的函数
      public BiComsumer,T> accumulator() {
            return (list,item)->list.add(item);
      }
  • 对结果容器应用最终转换:finisher
    在遍历完流之后,finisher方法必须返回在累积过程的最后要调用的一个函数,以便将累加器对象转换为整个集合操作的最终结果。
    public  Function,List> finisher() {
        return Function.identity();
    }
  • 合并两个结果容器: combiner
    combiner返回一个供规约操作使用的函数,它定义了对流的各个子部分进行并行处理,各个子部分规约所得的累加器要如何合并。
      public BinaryOperator> combiner() {
            return (list1,list2)->{
                    list1.addAll(list2);
                    return list1;
            }
      }
  • characteristics
    characteristics 会返回一个不可变的characteristics集合,它定义了收集器的行为。
    unordered 规约结果不接受流中项目的遍历和累积顺序的影响
    concurrent 可以多线程同时调用
    indentity_finish 表明是一个恒等函数

你可能感兴趣的:(用流收集数据)