Java8 特性笔记(三) Stream

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jeekmary/article/details/88047608

关于java8的stream也许有很多人听说过,但是不一定实际的用的很熟练,今天开始一点点的学习Java8有关Stream的相关知识,首先我们看一个例子

本博客依据 java 8 In Action 表写
需求: 在一个列表中找出小于某个数值的对象,并依次排序取出其中的值

1,Stream的基本认识

   static List<Dish> menu = Arrays.asList(
            new Dish("pork", false, 800, Dish.Type.MEAT),
            new Dish("beef", false, 700, Dish.Type.MEAT),
            new Dish("chicken", false, 400, Dish.Type.MEAT),
            new Dish("french fries", true, 530, Dish.Type.OTHER),
            new Dish("rice", true, 350, Dish.Type.OTHER),
            new Dish("season fruit", true, 120, Dish.Type.OTHER),
            new Dish("pizza", true, 550, Dish.Type.OTHER),
            new Dish("prawns", false, 300, Dish.Type.FISH),
            new Dish("salmon", false, 450, Dish.Type.FISH) );
     //采用的是java8 Stream
        private static List<String> getDishNameByStream(){
            return  menu.stream().filter(dish -> dish.getCalories()<400).sorted(Comparator.comparingInt(Dish::getCalories)).map(Dish::getName).collect(Collectors.toList());
        }
        //创痛的
        private static List<String> getDishNameByCollections(List<Dish> menu){
            List<Dish> lowCallories = new ArrayList<>();
            //找出卡路里小于400的
            for(Dish d: menu){
                if (d.getCalories()<400){
                    lowCallories.add(d);
                }
            }
            //将上面的list进行排序
            Collections.sort(lowCallories, Comparator.comparingInt(Dish::getCalories));
            List<String> dishName = new ArrayList<>();
            for (Dish d:lowCallories){
                dishName.add(d.getName());
            }
            return dishName;
        }

在这里我们能清楚的看到,实现同一功能的代码,使用java8的stream,我们能明显的节约了代码量,提高了开发效率,可能有的小伙伴认为,上面使用stream的方式太复杂了,很多东西都不懂,别着急我们会一步步深入的,上面的函数推导 也就是::部分我们在上一章节是有讲过的,有疑问的同学可以去看下我的上一篇博客

2,Stream介绍

Streams are an update to the Java API that lets you manipulate collections of data in a
declarative way (you express a query rather than code an ad hoc implementation for it). For now
you can think of them as fancy iterators over a collection of data. In addition, streams can be
processed in parallel transparently, without you having to write any multithreaded code! We
explain in detail in chapter 7 how streams and parallelization work. Here’s a taste of the benefits
of using streams: compare the following code to return the names of dishes that are low in
calories, sorted by number of calories, first in Java 7 and then in Java 8 using streams. Don’t
worry about the Java 8 code too much; we explain it in detail in the next sections!

在 java8 In Action这本书中,我们看到作者是这样理解java8的stream,stream是可以并行处理的,而你并不需要关注其中的细节

在这里插入图片描述
在这里插入图片描述

3,Stream简单的使用

stream是一种面向数据流的设计,在上面的介绍中,我们可以看到,stream就像一条流水线,根据不同的要求将产品进行加工,最后得到我们需要的产品

基本使用:

   static List<Dish> menu = Arrays.asList(
            new Dish("pork", false, 800, Dish.Type.MEAT),
            new Dish("beef", false, 700, Dish.Type.MEAT),
            new Dish("chicken", false, 400, Dish.Type.MEAT),
            new Dish("french fries", true, 530, Dish.Type.OTHER),
            new Dish("rice", true, 350, Dish.Type.OTHER),
            new Dish("season fruit", true, 120, Dish.Type.OTHER),
            new Dish("pizza", true, 550, Dish.Type.OTHER),
            new Dish("prawns", false, 300, Dish.Type.FISH),
            new Dish("salmon", false, 450, Dish.Type.FISH) );
   menu.stream();  //这样,这个集合就是一个数据流了
  	//接着我们就可以用不同的操作符对这个数据流进行操作
  	menu.stream().forEach(System,out::println);
  	//System,out::println 函数式推导,打印每一个值

在这里插入图片描述

Stream会将需要的操作都封装在Stream里面

上面所说的操作符都是比较简单的,这里大家要有一个简单的概念,后面我们一个个介绍到经常用的操作符的使用规范

3,Stream操作符分类

Stream的操作符是分为两类的 

1, 终止操作符 在源码我们会看到 terminal这个单词,就表示这个操作符执行完数据流就已经断了,后面不能再跟其他操作符了

2,中间操作符,这个操作符只是对数据起到过滤操作的作用,它并不会中断数据流,在源码里面我们可以看到Intermediate这个单词
  /**
     * Returns the count of elements in this stream.  This is a special case of
     * a <a href="package-summary.html#Reduction">reduction</a> and is
     * equivalent to:
     * <pre>{@code
     *     return mapToLong(e -> 1L).sum();
     * }</pre>
     *
     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
     *
     * @return the count of elements in this stream
     */
    long count();

4,Stream常见的操作符

filter 过滤
forEach 遍历每一个元素,这是一个终止操作符
limit  限制获取多少个元素
skip  跳过多少过元素
anyMatch 只要有一个满足条件就返回 True
map  遍历拿到每一个对象,进行用户需要的操作
reduce 根据一定规则计算后返回一个结果
distinct  去掉重复

针对上面的操作符我们还会有介绍的,读者可以看我后面的博客,我们那上面的一个Stream的例子来讲下

menu.stream().filter(dish -> dish.getCalories()<400).sorted(Comparator.comparingInt(Dish::getCalories)).map(Dish::getName).collect(Collectors.toList());
  • menu.stream() 就是创建一个Stream的数据流
  • filter 就是过滤了,里面是一个Predicate的函数式接口,我的前面文章有介绍函数式接口
  • sorted 就是排序了,这里传入的就是一个Comparator
  • map 操作符在这里是去Dish的名字,然后重新组成一个数据流
  • collect 这是一个终止操作符,后面就不能再进行数据stream的操作符了,这个函数里面也是需要传入一个Collectors的参数,这个Collectors的相关操作我在后面会继续介绍

猜你喜欢

转载自blog.csdn.net/jeekmary/article/details/88047608
今日推荐