2

前言:

在前面的 Java 8之stream介绍和使用Java 8之stream进阶 中讲了stream的使用方式和一些常用的方法,这篇文章就来演示一下stream的实际应用。


实际应用:

  1. 先创建一个订单类和商品类,每个订单都有年份、商品数量和商品对象属性,而商品类里面则包含了名字和价格属性。像这种结构的数据在日常开发中会经常看到,现在就使用stream来尝试满足各种不同的类型的数据获取。

    public class Goods {
        //商品名字
        private final String name;
        //商品价格
        private final String price;
    
        public Goods(String name, String price) {
        this.name = name;
        this.price = price;
        }
    
        public String getName() {
            return name;
        }
    
        public String getPrice() {
            return price;
        }
    
        @Override
        public String toString() {
            return "Goods{" +
                "name='" + name + '\'' +
                ", price='" + price + '\'' +
                '}';
        }
    }
    
    public class Order {
        //商品对象
        private final Goods goods;
        //订单日期
        private final int year;
        //商品数量
        private final int total;
    
        public Order(Goods goods, int year, int total) {
            this.goods = goods;
            this.year = year;
            this.total = total;
        }
    
        public Goods getGoods() {
            return goods;
        }
    
        public int getYear() {
            return year;
        }
    
        public int getTotal() {
            return total;
        }
    
        @Override
        public String toString() {
            return "Order{" +
                "goods=" + goods +
                ", year=" + year +
                ", total=" + total +
                '}';
        }
    }
  2. 模拟点数据

    public class testClass {
        static Goods bread = new Goods("面包", 10.0);
        static Goods milk = new Goods("牛奶", 12.0);
        static Goods juice = new Goods("果汁", 6.0);
        static Goods ham = new Goods("火腿", 20.0);
    
        static List<Order> orders = Arrays.asList(
        new Order(ham, 2011, 300),
        new Order(bread, 2012, 1000),
        new Order(bread, 2011, 400),
        new Order(milk, 2012, 710),
        new Order(milk, 2012, 700),
        new Order(juice, 2012, 950)
    );
  3. 下面来试使用stream获取不同条件下的数据

    //找出2011年所有的订单,按商品数量从低到高排序
    public static void findOne(){
        orders.stream()
        //先筛选年份
        .filter(trader -> trader.getYear()==2011)
        //再排序商品数量
        .sorted(Comparator.comparing(Order::getTotal))
        .collect(Collectors.toList())
        .forEach(System.out::println);
    }
    
    //获取所有订单的里所有商品的单价 
    public static void findTwo() {
        orders.stream()
        //先查出所有订单的里的商品价格
        .map(order -> order.getGoods().getPrice())
        //去重后转化为List类型
        //.distinct()
        //.collect(Collectors.toList())
        //或者直接转化为Set类型,自动去重
        .collect(Collectors.toSet())
        .forEach(System.out::println);
    }
    
    //查找订单中所有单价为12的商品
    public static void findThree() {
        orders.stream()
        //获取商品的流
        .map(order -> order.getGoods())
        //价格等于12的
        .filter(goods -> goods.getPrice().equals(12.0))
        //去重
        .distinct()
        .collect(Collectors.toList())
        .forEach(System.out::println);
    }
    
    //查所有商品的名字,拼接成一个符串
    public static void findFour() {
        String string = orders.stream()
        //获取所有商品的名字
        .map(order -> order.getGoods().getName())
        //去重
        .distinct()
        //使用reduce方法自行拼接
        //.reduce("",(str1,str2) -> str1 + str2);
        //或者使用joining方法自动拼接
        .collect(Collectors.joining());
        System.out.println(string);
    }
    
    //判断所有订单中是否有价格为20的商品
    public static void findFive() {
        boolean flag = orders.stream()
        //查询是否有符合条件的元素
        .anyMatch(order -> order.getGoods().getPrice().equals(20.0));
        System.out.println(flag);
    }
    
    //所有订单中商品价格12的商品累计数量
    public static void findSix() {
        int num = orders.stream()
        //筛选出价格12的商品
        .filter(order -> order.getGoods().getPrice().equals(12.0))
        //获取价格为12的商品的金额组成的流
        .map(Order::getTotal)
        //累加所有的金额
        .reduce(0, Integer::sum);
        System.out.println(num);
    }
    
    //找出所有订单中最大的数量
    public static void findSeven() {
        int max = orders.stream()
        //获取所有订单的数量
        .map(Order::getTotal)
        //找到最大的
        .reduce(0, Integer::max);
        System.out.println(max);
    }
    
    //找出所有订单中商品数量最小的
    public static void findEight() {
        orders.stream()
        //获取所有订单的数量
        .map(Order::getTotal)
        //找到最大的
        .reduce(Integer::min)
        //如果返回的结果不是空就打印
        .ifPresent(System.out::println);
    }

总结:

以上就是stream的实际应用,上述情况在日常开发中还是很常见到的,如果不用stream的代码写起来不仅非常繁琐还容易出错,得新建很多个集合不停的遍历、判断和存取,但是用了stream之后就非常的简单,代码也很清晰,后面还会介绍到stream别的特性和用法。


Half
238 声望17 粉丝

The Long Way Round.