Java Stream,解放你的for循环

一个图书管理的例子

现有一批图书的信息,图书管理员需要对目前的图书做一个大致的了解,需要从不同维度进行统计

序号书名发行时间类别楼层价格
1红楼梦1994-01-02文学120.80
2java编程思想1999-11-02技术250.40
3史记2001-11-02历史332
4圣经1979-11-02外国文学215.5
5高等数学2008-11-02教材515
6单片机2009-11-02教材511.5

于是我们拷贝了整个excel的数据,直接拿原始文本进行处理.
1.定义图书实体类

    static class Book{
        //主题
        String category;
        //发布时间
        Date publishDate;
        //书名
        String name;
        //价格
        Double price;

        Book(){}

        Book(String category, Date publishDate,String name,Double price){
            this.category = category;
            this.publishDate = publishDate;
            this.name = name;
            this.price = price;
        }
    }

2.将文本转换成结构化数据

     public void createBookList()  {

        //从Excel中直接复制出来的格式
        String excelData = "1\t红楼梦\t1994-01-02\t文学\t1\t20.80\n" +
                "2\tjava编程思想\t1999-11-02\t技术\t2\t50.40\n" +
                "3\t史记\t2001-11-02\t历史\t3\t32\n" +
                "4\t圣经\t1979-11-02\t外国文学\t2\t15.5\n" +
                "5\t高等数学\t2008-11-02\t教材\t5\t15\n" +
                "6\t单片机\t2009-11-02\t教材\t5\t11.5";
        //使用Pattern.splitAsStream(),将字符串分割成流
        Pattern pattern = Pattern.compile("\\n");
        Stream<String> stringStream = pattern.splitAsStream(excelData);
        //或使用以下方式获取每一行的数据
        //Stream<String> stringStream = new BufferedReader(new StringReader(excelData)).lines();

        books = stringStream.map(x->{
            String[] cols = x.split("\\t");
            String category = cols[3];
            String name = cols[1];
            Double price = Double.parseDouble(cols[5]);
            Date publishDate = null;
            try {
                publishDate = new SimpleDateFormat("yyyy-MM-dd").parse(cols[2]);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return new Book(category,publishDate,name,price);
        }).collect(Collectors.toList());
    }

3.统计图书信息

    public void stream(){
        //逐行打印出所有书名
        books.stream().map(Book::getName).forEach(System.out::println);
        //红楼梦
        //java编程思想
        //史记
        //圣经
        //高等数学
        //单片机

        //peek 不会中断流
        List<Book> newBooks = books.stream().peek(x->x.setPrice(100*x.getPrice())).sorted(Comparator.comparingDouble(Book::getPrice)).collect(Collectors.toList());
        //foreach 会中断流操作
        books.stream().forEach(x->x.setPrice(100*x.getPrice()));

        //将书名用书名号”《》“分割打印
        String bookNames = books.stream().map(Book::getName).collect(Collectors.joining("》《","《","》")).toString();
        // 《红楼梦》《java编程思想》《史记》《圣经》《高等数学》《单片机》

        //获得对图书价格的统计信息
        DoubleSummaryStatistics summaryStatistics = books.stream().collect(Collectors.summarizingDouble(Book::getPrice));

        double sumPrice = summaryStatistics.getSum(); //145.2
        //求出所有图书平均价格
        double averagePrice = summaryStatistics.getAverage(); // 24.2
        //求出所有图书最低价格
        double minPrice = summaryStatistics.getMin(); // 24.2
        //求出所有图书最高价格
        double maxPrice = summaryStatistics.getMax(); // 24.2


        //统计各类别的图书对应的总价
        Map<String,Double> categorySumMap = books.stream()
                .collect(Collectors.groupingBy(Book::getCategory,Collectors.summingDouble(Book::getPrice)));
        //技术->50.4,文学->20.8,外国文学->15.5,历史->32.0,教材->26.5


        //根据类别统计图书平均价格
        Map<String,Double> categoryAverageMap = books.stream()
                .collect(Collectors.groupingBy(Book::getCategory,Collectors.collectingAndThen(Collectors.summarizingDouble(Book::getPrice),x->x.getAverage())));
        //技术->50.4,文学->20.8,外国文学->15.5,历史->32.0,教材->13.25

        //按发布时间排序
        List<Book> sortedBookList = books.stream().sorted((x1,x2)->{
           return x1.getPublishDate().after(x2.getPublishDate())?1:-1;
        }).collect(Collectors.toList());

        //将图书分成教材书和非教材书
        Map<Boolean,List<Book>> booleanListMap = books.stream().collect(Collectors.partitioningBy(x->"教材".equals(x.getCategory())));

    }

使用Stream生成数据和分页

    public void iterate(){

        // 迭代器,从0开始,新的元素 = 上一个元素 + 2 , 共迭代六次结束
        List<Integer> list  = Stream.iterate(0,x -> x+2).limit(6).collect(Collectors.toList());

        list.stream();  // 0 2 4 6 8 10

        //跳过前n个,(n=2)
        list.stream().skip(2); // 4 6 8 10
        //只取前n个
        list.stream().limit(2); // 0 2

        //skip 和 limit 可以用来做分页
        // pageSize = 2 ,  取第4页数据时,可以
        int pageSize = 2;  int pageNum = 4 ;
        Stream.iterate(1,x->x+1).limit(100).skip((pageNum-1) * pageSize).limit(pageSize).forEach(System.out::println);
        // 7 , 8

        // 生成随机数
        Stream.generate(Math::random).limit(4).forEach(System.out::println); //生成4个小于1的随机数
        new Random().ints(10).forEach(System.out::println);//生成10个整形数
        new Random().ints(10,0,10).forEach(System.out::println); //生成10个整形数,大小在0-10之间

    }

Stream操作分类

|  |  ||--|--||  4  |

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值