Java8新特性之Stream流

Java8新特性之Stream流

什么是Stream流

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。 是一个来自数据源的元素队列并支持聚合操作

  1. 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  2. 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  3. 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

Stream特点

  • 无存储。Stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
  • 为函数式编程而生。对Stream的任何修改都不会修改背后的数据源,比如对Stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新Stream。
  • 惰式执行。Stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
  • 可消费性。Stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

Stream流操作

1: 创建Stream

主要负责新建一个Stream流,或者基于现有的数组、List、Set、Map等集合类型对象创建出新的Stream流。

API功能说明
stream()创建出一个新的stream串行流对象
parallelStream()创建出一个可并行执行的stream流对象
Stream.of()通过给定的一系列元素创建一个新的Stream串行流对象

示例

    /**
     * 通过集合生成,应用中最常用的一种
     */
    List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5);
    Stream<Integer> stream1 = integerList.stream();

    /**
     * 通过数组生成
     */
    int[] intArr = new int[]{1, 2, 3, 4, 5};
    IntStream stream2 = Arrays.stream(intArr);


    /**
     * 创建并行流对象
     */
    Stream<Integer> promotionStream = integerList.parallelStream();

2: 中间管道

​ 负责对Stream进行处理操作,并返回一个新的Stream对象,中间管道操作可以进行叠加

API功能说明
filter()按照条件过滤符合要求的元素, 返回新的stream流
map()将已有元素转换为另一个对象类型,一对一逻辑,返回新的stream流
flatMap()将已有元素转换为另一个对象类型,一对多逻辑,即原来一个元素对象可能会转换为1个或者多个新类型的元素,返回新的stream流
limit()仅保留集合前面指定个数的元素,返回新的stream流。limit的参数值必须>=0,否则将会抛出异常
skip()跳过集合前面指定个数的元素,返回新的stream流。skip的参数值必须>=0,否则将会抛出异常
concat()将两个流的数据合并起来为1个新的流,返回新的stream流
distinct()对Stream中所有元素进行去重,返回新的stream流
sorted()对stream中所有的元素按照指定规则进行排序,返回新的stream流
peek()对stream流中的每个元素进行逐个遍历处理,返回处理后的stream流

示例:

filter()
    /**
    * filter筛选
    * 通过使用filter方法进行条件筛选,filter的方法参数为一个条件
    */
    List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);
    Stream<Integer> stream = integerList.stream().filter(i -> i > 3);
map()

主要用于List 循环获取Entity的属性值

    /**
    * map流映射(所谓流映射就是将接受的元素映射成另外一个元素)
    */
    List<String> stringList = Arrays.asList("str1", "str2", "str3", "str5");
    Stream<Integer> streams = stringList.stream().map(String::hashCode);
flatMap()

将已有元素转换为另一个对象类型,一对多逻辑

    /**
    * flatMap流转换(将一个流中的每个值都转换为另一个流)
    */
    List<String> wordList = Arrays.asList("Hello", "World");

    List<String> strList = wordList.stream()
    .map(w -> w.split("r"))
    .flatMap(Arrays::stream)
    .distinct()
    .collect(Collectors.toList());
limit()
    /**
    * limit返回指定流个数
    * 通过limit方法指定返回流的个数,limit的参数值必须>=0,否则将会抛出异常
    */
    List<String> wordList = Arrays.asList("Hello", "World","!");

    Stream<String> limitStream = wordList.stream().limit(1);
skip()
    /**
    * skip跳过流中的元素
    * 通过skip方法跳过流中的元素,例子中打印出来的数据: World,! 。skip的参数值必须>=0,否则将会抛出异常
    */
    List<String> wordList = Arrays.asList("Hello", "World","!");

    Stream<String> limitStream = wordList.stream().skip(1);
concat()
    Stream<String> streamOne = Stream.of("Hello");
    Stream<String> streamTwo = Stream.of("World");
    Stream<String> concatStream = Stream.concat(streamOne, streamTwo);
distinct()
    /**
    * distinct主要用来去重,以下代码片段使用 distinct 对元素进行去重
    */
    List<String> wordList = Arrays.asList("Hello", "World","!","Hello","!");

    Stream<String> limitStream = wordList.stream().distinct();
sorted()
        /**
         * sorted对流进行排序
         * sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法进行排序
         */
        List<Integer> integerList = Arrays.asList(1, 3,2,10,7);
        Stream<Integer> sortedStream = integerList.stream().sorted();

        /**
         * 通过比较器比较
         */
        List<String> wordList = Arrays.asList("Hello", "World","!","Hello","!");
        wordList.stream().sorted(((str1, str2) -> {
            if (str1.length()> str2.length()) {
                return -1;
            } else {
                return 1;
            }
        }));
peek()
        /**
         * peek()属于中间方法,没有结束
         * peek只能作为管道中途的一个处理步骤,而没法直接执行得到结果,其后面必须还要有其它终止操作的时候才会被执行
         */
        List<String> wordList = Arrays.asList("Hello World!");
        //没有输出
        wordList.stream().peek(sentence -> System.out.println(sentence));
        //输出结果
        wordList.stream().peek(sentence -> System.out.println(sentence)).count();

3: 终止管道

​ 通过终止管道操作之后,Stream流将会结束,最后可能会执行某些逻辑处理,或者是按照要求返回某些执行后的结果数据

API功能说明
count()返回stream处理后最终的元素个数
max()返回stream处理后的元素最大值
min()返回stream处理后的元素最小值
findFirst()找到第一个符合条件的元素时则终止流处理
findAny()找到任何一个符合条件的元素时则退出流处理,这个对于串行流时与findFirst相同,对于并行流时比较高效,任何分片中找到都会终止后续计算逻辑
anyMatch()返回一个boolean值,类似于isContains(),用于判断是否有符合条件的元素
allMatch()返回一个boolean值,用于判断是否所有元素都符合条件
noneMatch()返回一个boolean值, 用于判断是否所有元素都不符合条件
collect()将流转换为指定的类型,通过Collectors进行指定
toArray()将流转换为数组
iterator()将流转换为Iterator对象
foreach()无返回值,对元素进行逐个遍历,然后执行给定的处理逻辑
count()

count用来统计流中的元素个数。

        /**
         * 统计流中元素个数
         * 通过使用count方法统计出流中元素个数
         */
        List<String> wordList = Arrays.asList("Hello","World","!!");
        long count = wordList.stream().count();
max()/min()

获取流中最小最大值

        List<Integer> integerList = Arrays.asList(100,111,22,3,343);
        Optional<Integer> min = integerList.stream().min(Integer::compareTo);
        Optional<Integer> max = integerList.stream().max(Integer::compareTo);
findFirst()

查找大于100的第一个值

		  /**
         * 查询列表中大于100的数值
         */
        List<Integer> integerList = Arrays.asList(100,111,22,3,343);
        Optional<Integer> result = integerList.stream().filter(v -> v > 100).findFirst();
findAny()

找到任何一个符合条件的元素时则退出流处理

        List<Integer> integerList = Arrays.asList(100,343,22,3,111);
        Optional<Integer> result = integerList.stream().filter(v -> v > 100).findAny();
        System.out.println(result.get());
anyMatch()
		  /**
         * 查询列表中是否包含111的字符串
         */
        List<String> integerList = Arrays.asList("100", "343","22","3","111");
        boolean b = integerList.stream().anyMatch("111"::equals);
allMatch()

这个和anyMatch() 的类似,列表里面的元素都要匹配上。

noneMatch()

这个和anyMatch() 的类似,列表里面的元素都不能匹配上。

剩下的都是一些比较简单的,这里不在进行举例了。

优势和劣势

相对于foreach的方式,Stream有很多优势:

  1. 代码简洁,逻辑清洗
  2. 函数式接口,延迟执行的特性,中间管道操作不管有多少步骤都不会立即执行,只有遇到终止操作的时候才会开始执行,可以避免一些中间不必要的操作消耗
  3. 并行流场景效率会比迭代器逐个循环更高

劣势:

  1. 代码调试不是很方便
  2. 开发者需要去适应这种模式

以上就是本篇文章的所有内容,请大家多多指教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大伟攀高峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值