Java8中你可能不知道的一些地方之Stream实战三

664 阅读11分钟

汇总

汇总操作在Stream流操作比较常见,比如计算总数,求平均等操作,常用方法如下:

相关操作如下

  • 筛选所有有效订单 返回订单总数
System.out.println("count结果:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .collect(Collectors.counting())
                  );
System.out.println("count结果:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .count()
                  );
  • 返回订单总金额
System.out.println("订单总金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .collect(Collectors.summarizingDouble(Order::getTotal))
                  );
System.out.println("订单总金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .mapToDouble(Order::getTotal)
                            .sum()
                  );
System.out.println("订单总金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .map(Order::getTotal)
                            .reduce(Double::sum)
                            .get()
                  );
  • 返回用户id=20 有效订单平均每笔消费金额
System.out.println("用户id=20 有效订单平均每笔消费金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .filter((order -> order.getUserId()==20))
                            .collect(Collectors.averagingDouble(Order::getTotal))
                  );
System.out.println("用户id=20 有效订单平均每笔消费金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .filter((order -> order.getUserId()==20))
                            .mapToDouble(Order::getTotal)
                            .average()
                            .getAsDouble()
                  );

System.out.println("用户id=20 有效订单平均每笔消费金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .filter((order -> order.getUserId()==20))
                            .collect(Collectors.summarizingDouble(Order::getTotal))
                            .getAverage()
                  );
  • 筛选所有有效订单 并计算订单总金额
System.out.println("订单总金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .collect(Collectors.summingDouble(Order::getTotal))
                  );

最值

  • 筛选所有有效订单 并计算最小订单金额
System.out.println("最小订单金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .map(Order::getTotal)
                            .collect(Collectors.minBy(Double::compare))
                  );
  • 筛选所有有效订单 并计算最大订单金额
// 筛选所有有效订单 并计算最大订单金额
System.out.println("最大订单金额:"+
                        ordersList.stream()
                            .filter((order) -> order.getIsValid() == 1)
                            .map(Order::getTotal)
                            .collect(Collectors.maxBy(Double::compare))
                  );

分组&分区

1 分组

groupingBy 用于将数据分组,最终返回一个 Map 类型 ,groupingBy 第二参数用于实现多级分组

  • 根据有效订单支付状态进行分组操作
Map<Integer,List<Order>> g01=ordersList.stream()
                                .filter((order) -> order.getIsValid() == 1)
                                .collect(Collectors.groupingBy(Order::getStatus));
g01.forEach((status,order)->{
    System.out.println("----------------");
    System.out.println("订单状态:"+status);
    order.forEach(System.out::println);
});
  • 筛选有效订单,根据用户id 和 支付状态进行分组
Map<Integer,Map<String,List<Order>>> g02= ordersList.stream()
                    .filter((order) -> order.getIsValid() == 1)
                    .collect(Collectors.groupingBy(Order::getUserId,
                              Collectors.groupingBy((o)->{
                                    if(o.getStatus()==0){
                                        return "未支付";
                                    }else if (o.getStatus()==1){
                                        return "已支付";
                                    }else if (o.getStatus()==2){
                                        return "待发货";
                                    }else if (o.getStatus()==3){
                                        return "已发货";
                                    }else if (o.getStatus()==4){
                                        return "已接收";
                                    } else{
                                        return "已完成";
                                    }
                                }
                                ))
                            );
g02.forEach((userId,m)->{
    System.out.println("用户id:"+userId+"-->有效订单如下:");
    m.forEach((status,os)->{
        System.out.println("状态:"+status+"---订单列表如下:");
        os.forEach(System.out::println);
    });
    System.out.println("-----------------------");
});

2 分区

分区与分组的区别在于,分区是按照 true 和 false 来分的,因此partitioningBy 接受的参数的 lambda 也是 T -> boolean

  • 分区操作-筛选订单金额>1000 的有效订单
Map<Boolean,List<Order>> g03= ordersList.stream()
            .filter((order) -> order.getIsValid() == 1)
            .collect(Collectors.partitioningBy((o)->o.getTotal()>1000));
g03.forEach((b,os)->{
    System.out.println("分区结果:"+b+"--列表结果:");
    os.forEach(System.out::println);
});
  • 拼接操作-筛选有效订单并进行拼接
String orderStr=ordersList.stream()
            .filter((order) -> order.getIsValid() == 1)
            .map(Order::getOrderNo)
            .collect(Collectors.joining(","));
System.out.println(orderStr);

流的应用

Java8引入Stream流操作,使得对元素的处理更加的方便快捷,通过Stream提供的相关方法很好的结合Lambda、函数式接口、方法引用等相关内容,使得流的处理相比较原始集合处理代码极大简化,Stream支持函数的链式调用,代码上更加紧凑同时Stream支持的元素的并行化处理提高了程序的执行性能。

对于Stream流的应用通常在集合元素数据处理上特别是对元素需要进行多次处理的情况,同时对于函数式编程的味道更加浓重,也是以后开发的一个趋势。

好了,Java8核心特性之Stream流就介绍到这里了,应该是非常详尽了,希望大家喜欢。