java8 stream收集数据

 参考书籍《Java 8 实战》

// 实体类
public class Goods {

    private String name;

    private Integer price;

    public static List<Goods> getGoods() {
        List<Goods> goods = new ArrayList<>();
        goods.add(new Goods("铅笔", 10));
        goods.add(new Goods("面包", 20));
        goods.add(new Goods("冰箱", 100));
        goods.add(new Goods("水", 2));
        goods.add(new Goods("口香糖", 8));
        return goods;
    }
}

将stream汇总为一个值

  • 查找流中的最大最小值
        // 求出价格最高的商品
        Goods good = Test.goods.stream().collect(Collectors.maxBy(Comparator.comparing(Goods::getPrice))).get();
        // 可以简化为
        Goods good2 = Test.goods.stream().max(Comparator.comparing(Goods::getPrice)).get();
        System.out.println(JSON.toJSONString(good));
        System.out.println(JSON.toJSONString(good2));
// 价格最低的用min
  • 元素汇总

    例如对元素进行求和、求平均值等。

        // 将价格求和
        Integer sum = Test.goods.stream().collect(Collectors.summingInt(Goods::getPrice));
        // 可以简化为
        Integer sum2 = Test.goods.stream().mapToInt(Goods::getPrice).sum();

        // 将价格求平均数
        Double d1 = Test.goods.stream().collect(Collectors.averagingInt(Goods::getPrice));
        System.out.println(sum);
        System.out.println(sum2);
        System.out.println(d1);

        // 可以通过summarizingInt方法获取收集器,然后再收集里再去获取最大值、最小值、平均数等
        IntSummaryStatistics statistics = Test.goods.stream().collect(Collectors.summarizingInt(Goods::getPrice));
        System.out.println(statistics.getMax());
        System.out.println(statistics.getAverage());
        System.out.println(statistics.getCount());
        System.out.println(statistics.getSum());
        System.out.println(statistics.getMin());
  • 拼接字符串

使用Collectors.joining()方法

        // 将商品名称品接起来
        String str = Test.goods.stream().map(Goods::getName).collect(Collectors.joining());
        System.out.println(str);
        // 如果需要间隔符
        String str2 = Test.goods.stream().map(Goods::getName).collect(Collectors.joining(","));
        System.out.println(str2);

 

元素分组

  • 使用groupBy进行分组
        // 根据类型进行分组
        Map<String, List<Goods>> map = goods.stream().collect(Collectors.groupingBy(Goods::getType));
        System.out.println(JSON.toJSONString(map));
        // 如果想要更个性化一点,例如根据价格分组
        Map<String, List<Goods>> map2 = goods.stream().collect(Collectors.groupingBy(a -> {
            if (a.getPrice() > 1000) {
                return "太贵了";
            } else if ((a.getPrice() > 100)) {
                return "可以接受";
            } else {
                return "挺便宜";
            }
        }));
        System.out.println(JSON.toJSONString(map2));
  • 多级分组
        // 先根据类型分组,再根据价格分组
        Map<String, Map<String, List<Goods>>> map = goods.stream().collect(Collectors.groupingBy(Goods::getType,
                Collectors.groupingBy(b -> {
                    if (b.getPrice() > 4000) {
                        return "太贵了";
                    } else if ((b.getPrice() > 100)) {
                        return "可以接受";
                    } else {
                        return "挺便宜";
                    }
                })
        ));
        System.out.println(JSON.toJSONString(map));
  • 按照分组收集数据
        // 求出每个分类下的个数
        Map<String, Long> count = goods.stream()
                .collect(Collectors.groupingBy(Goods::getType, Collectors.counting()));
        System.out.println(JSON.toJSONString(count));
        // 求出每个分类下面最贵的商品
        Map<String, Optional<Goods>> collect = goods.stream()
                .collect(Collectors.groupingBy(Goods::getType,
                        maxBy(comparingInt(Goods::getPrice))));
        // 使用collectingAndThen将 Optional<Goods>转为goods
        // collectingAndThen 接受两个参数,要转换的收集器以及转换函数,并返回另一个收集器
        Map<String, Goods> goodsMap = goods.stream()
                .collect(Collectors.toMap(Goods::getType, Function.identity(), BinaryOperator.maxBy(comparingInt(Goods::getPrice))));

        // 根据type分组,value是物品名称
        // mapping接受两个参数,要一个是对流中的元素做变换,另一个则将变换的结果对象收集起来
        Map<String, List<String>> nameList = goods.stream().collect(groupingBy(Goods::getType,
                mapping(Goods::getName, toList())
        ));
        System.out.println(JSON.toJSONString(nameList));

 

元素分区

分区和分组的概念及其类似。

        // 将价格大于400的分为一组,小于400的分为一组
        Map<Boolean, List<Goods>> maps =
                goods.stream().collect(Collectors.partitioningBy(a -> a.getPrice() > 400));
        System.out.println(maps.get(true));
        System.out.println(maps.get(false));
        // 当然根据groupingBy也可以实现
        Map<Boolean, List<Goods>> maps2 = goods.stream().collect(Collectors.groupingBy(a -> {
            if (a.getPrice() > 400) {
                return true;
            } else {
                return false;
            }
        }));
        System.out.println(maps2.get(true));
        System.out.println(maps2.get(false));

        // 分区里可以进行二级分组,先根据价格分区,然后再根据类型分组
        Map<Boolean, Map<String, List<Goods>>> map3 = goods.stream().collect(Collectors.partitioningBy(a -> a.getPrice() > 400,
                Collectors.groupingBy(Goods::getType)));

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值