Java8实战笔记(三)

用流收集数据

  1. 查找流中的最大值和最小值

    • Collectors.maxBy():计算流中的最大值,该收集器接收一个Comparator参数来 比较流中的元素

      // 创建一个Comparator来根据所含热量对菜肴进行比较,并把它传递给Collectors.maxBy
      Comparator<Dish> dishCaloriesComparator = Comparator.comparingInt(Dish::getCalories);
      Optional<Dish> mostCalorieDish = menu.stream().collect(Collectors.maxBy(dishCaloriesComparator));
      
    • Collectors.minBy():计算流中的最小值,该收集器接收一个Comparator参数来 比较流中的元素

  2. 汇总

    • Collectors.summingInt():它可接受一 个把对象映射为求和所需int的函数,并返回一个收集器;该收集器在传递给普通的collect方法后即执行我们需要的汇总操作。(Collectors.summingLong()和Collectors.summingDouble()用法完全一样)

      int totalCalories = menu.stream().collect(summingInt(Dish::getCalories));
      
    • Collectors.averagingInt():计算数值的平均数。(Collectors.averagingLong()和Collectors.averagingDouble()用法完全一样)

      double avgCalories = menu.stream().collect(averagingInt(Dish::getCalories));
      
    • Collectors.summarizingInt():该方法可以计算出流中元素个数、总和、最大值、最小值。计算数值的平均数。(Collectors.summarizingLong()和Collectors.summarizingDouble()用法完全一样)

      // 收集器会把所有这些信息收集到一个叫作IntSummaryStatistics的类里,它提供了方便的取值(getter)方法来访问结果
      IntSummaryStatistics menuStatistics = menu.stream().collect(summarizingInt(Dish::getCalories));
      
  3. 连接字符串

    • Collectors.join():对流中每一个对象应用toString方法得到的所有字符串连接成一个字符串,参数可接受一个分隔符。

      // 把菜单中所有菜肴的名称连接起来
      String shortMenu = menu.stream().map(Dish::getName).collect(Collectors.join());
      // 如果Dish类由一个toString方法返回菜肴的名称,则无需用提取每一道菜名称的函数来对原流做映射就能够得到相同的结果
      String shortMenu = menu.stream().collect(joining()); 
      
  4. 分组

    • Collectors.groupingBy():根据一个或多个属性对集合中的项目进行分组。

      // 把菜单中的菜按照类型进行分类
      Map<Dish.Type, List<Dish> dishesByType = menu.stream().collect(groupingBy(Dish::getType));
      
    • 多级分组:使用一个由双参数版本的Collectors.groupingBy工厂方法创建的收集器,它除了普通的分类函数之外,还可以接受collector类型的第二个参数。把第二个groupingBy收集器传递给外层收集器来实现多级分组,但进一步说,传递给第一个groupingBy的第二个收集器可以是任何类型,而不一定是另一个groupingBy

      // 对菜单中的菜肴同时按照类型和热量进行分组
      Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishjesByTypeCaloricLevel = menu.stream().collect(
          // 一级分类函数
          groupingBy(Dish::getType,
              // 二级分类函数
          	groupingBy(dish -> {
                  if (dish.getCalories() <= 400) return CaloricLevel.DIEF;
                  else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;
                  else return CaloricLevel.FAT;
              })
          )
      );
      
      // 数一数菜单中每类菜有多少个,可以传递counting收集器作为groupingBy收集器的第二个参数
      Map<Dish.Type, Long> typesCount = menu.stream().collect(groupingBy(Dish::getType, counting()));
      
  5. 分区

    • partitioningBy():分区是分组的特殊情况,它由一个谓词(返回一个布尔值的函数)作为分类函数,它称分区函数。分区函数返回一个布尔值,这意味着得到的分组Map的键类型是Boolean,于是它最多可以分为两组——true是一组,false是一组。

      // 把菜单按照素食和非素食分开
      Map<Boolean, List<Dish>> partitionedMenu = menu.stream().collect(partitioningBy(Dish::isVegetarian));
      
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值