美文网首页
用流收集数据

用流收集数据

作者: 上海马超23 | 来源:发表于2017-07-15 11:02 被阅读0次

归约和总结

// 菜单里有多少道菜
menu.stream().count();

// 热量最高的菜
Comparator<Dish> calComparator = Comparator.comparingInt(Dish::getCalories);
menu.stream().collect(maxBy(calComparator));

// 汇总
menu.stream().collect(summingInt(Dish::getCalories));
// 平均数
menu.stream().collect(averagingInt(Dish::getCalories));

// 连接字符串
String s = menu.stream().map(Dish::getName).collect(joining(","));

// 广义上的归约总结
// 3个参数版本: 初始值、转换函数、归约函数
menu.stream().collect(reducing(0, Dish::getCalories, (i, j) -> i + j));
// 1个参数版本
menu.stream().collect(reducing((d1, d2) -> d1.getCalories() > d2.getCalories() ? d1 : d2));

分组

// 按菜的热量分类
Map<CaloricLevel, List<Dish>> dishByType = menu.stream().collect(groupingBy(dish -> {
  if (dish.getCalories() <= 400) return CaloricLevel.DIET;
  else return CaloricLevel.FAT;
}));

// 先按类型再按热量分类
Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishesByTypeCaloric = 
  groupingBy(Dish::getType,
    groupingBy( dish - > {
      if (dish.getCalories() <= 400) return CaloricLevel.DIET;
      else return CaloricLevel.FAT;
  })));

// 转换收集器的结果类型
Map<Dish.Type, Dish> maxCaloricByType = 
  menu.stream().collect(groupingBy(Dish::getType,
    // //转换函数collectingAndThen,接受2个参数,要转换的收集器maxBy,和转换函数Optional::get
    collectingAndThen(maxBy(comparingInt(Dish::getCalories)), 
      Optional::get)); 

// 组合2个收集器
Map<Dish.Type, Dish> maxCaloricByType = 
  menu.stream().collect(groupingBy(Dish::getType, 
    // mapping方法接受2个参数:一个是对流中元素做变化的函数,另一个是收集器负责收集函数结果
    mapping( dish -> {if ...else }, toSet()
)));

分区

// 分区是分组的特殊情况,返回boolean值的分组就是分区
// 例如对素食和非素食按类型分组,得到二级Map
Map<Boolean, Map<Dish.Type, List<Dish>>> vegetarianDishesByType =
  menu.stream().collect(
    partitioningBy(Dish::isVegetarian,
      groupingBy(Dish::getType)));

收集器接口

// T是流的泛型,A是累加器的类型,R是收集操作得到的对象类型
public interface Collector<T, A, R> {
  // 建立一个新的结果容器
  Supplier<A> supplier();
  // 例如:
  public Supplier<List<T>> supplier() {
    return ArrayList::new;
  }  

  // 将元素添加到结果容器
  BiConsumer<A, T> accumulator();
  // 例如:
  public BiConsumer<List<T>, T> accumulator() {
    return (list, item) -> list.add(item);
  }
  
  // 对结果容器应用最终转换
  Function<A, R> finisher();
  // 例如:
  public Function<List<T>, List<T>> finisher() {
    return Function.identity();
  }

  // 合并两个结果容器
  BinaryOperator<A> combiner();
  // 例如:
  public BinaryOperator<List<T>> combiner() {
    return (list1, list2) -> {
      list1.addAll(list2);
      return list1;
    }
  }  
  
  // 返回枚举集合:UNORDERED, CONCURRENT, IDENTITY_FINISH
  Set<Characteristics> characteristics();
}

可以不用实现Collector进行自定义收集

menuStream.collect(ArrayList::new, List::add, List::addAll);

相关文章

  • 用流收集数据

    找出流中最大和最小元素 汇总 字符串连接joining工厂方法返回的收集器会把对流中每一个对象应用tostring...

  • 用流收集数据

    归约和总结 分组 分区 收集器接口 可以不用实现Collector进行自定义收集

  • 用流收集数据

    Collection、Collector和Collect的区别: Collection:Collection是集合...

  • 心得和感悟

    有数据才好分析和管理,学会收集数据,可以从自己日常的时间流,现金流,注意力分配等来锻炼收集数据的能力。

  • java8用流收集数据

    收集器简介 Collector 函数式编程相对于指令式编程的一个主要优势:你只需要指出希望的结果“做什么”,而不用...

  • java8用流收集数据

    用流收集数据 汇总 查找最大值和最小值 连接字符串 广义的归约汇总 reducing需要说那个参数: 1.起始值 ...

  • Stream API(二)用流收集数据

    Java8中提供了Collectors类来做收集器。以下介绍都是使用流中的collect方法接收Collector...

  • 运用数据报表,让你的应用数据一目了然

    在轻流,管理员可以轻松地通过表单收集收据,通过流程流转数据。可是,轻流的强大之处岂止于数据的收集和流转,轻流还致力...

  • Java8-流-用流收集数据和并行流

    收集器简介 汇总 并行流 欢迎访问本人博客查看原文:http://wangnan.tech 收集器简介 对流调用c...

  • 流式编程

    日常使用 前言:依旧使用购物车的数据 生成流的方式 收集器 收集器:将流的元素累计成一个结果比如:将筛选过的数据,...

网友评论

      本文标题:用流收集数据

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