Java之stream流浅析

Stream流是Java8中提供的一个重要新特性,它允许开发人员以声明方式处理集合。其中parallelStream其实就是一个并行执行的流,它通过默认的ForkJoinPool,可能提高你的多线程任务的速度。
Stream流特点如下

  • stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果;
  • stream不会改变数据源,通常情况下会产生一个新的集合;
  • stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行;
  • stream不可复用,对一个已经进行了终端操作的流再次调用会抛出异常;

Stream流接口中定义了许多对于集合的操作方法,主要分为两类:中间操作和终端操作。
在这里插入图片描述

  • 中间操作:返回一个流,通过这种方式可以将多个中间操作连接起来,形成一个调用链,从而转换为另一个流。除非调用链后存在一个终端操作,否则中间操作对流不会进行任何结果处理。
  • 终端操作:返回一个具体的结果,如list等。

常见的中间操作方法有:limit、skip、distinct、sorted等。
常见的终端操作方法有:forEach、count、toArray、reduce等。
常见的收集操作方法有:collect。
使用Stream流的方式操作完毕后,通过收集方法collect将数据收集到集合中,工具类Collectors提供了具体的收集方式,如下

  • toList:把元素收集到List集合中;
  • toSet:把元素收集到Set集合中;
  • toMap:把元素收集到Map集合中;

Stream性能

  • 在少数据量场景(size<1000)
    stream流的foreach处理效率不如iterator迭代的效率,但实际上这些处理任务本身运行实际都低于毫秒,这点效率的差距对普通业务几乎没有影响,而stream流却可以使得代码更简单优雅;
  • 在多数据量场景(size>10000)
    stream流的foreach处理效率高于iterator迭代的效率,特别是使用了并行流,在cpu恰好将线程分配到多个核心的条件下,效率很高。
  • parallelStream并行流
    parallelStream受cpu环境影响很大,当没分配到多个cpu核心时,加上引入了forkJoinPool的开销,运行效率还不如stream流。

下面分别对for循环、foreach循环、stream.foreach循环、parallelStream.foreach循环的性能进行测试

public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 1000; i++) {
            list.add(i);
        }
        Long startTime = System.currentTimeMillis();
        forMethod(list);
        Long endTime = System.currentTimeMillis();
        System.out.println("result:" + (endTime - startTime));//29 15 31 15 16
    }

    private static void forMethod(List<Integer> list) {
        for (Integer i : list) {
            System.out.println("------" + i);
        }
    }
public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 1000; i++) {
            list.add(i);
        }
        Long startTime = System.currentTimeMillis();
        foreachMethod(list);
        Long endTime = System.currentTimeMillis();
        System.out.println("result:" + (endTime - startTime));//85 80 84 84 85
    }

    private static void foreachMethod(List<Integer> list) {
        list.forEach(integer -> {
            System.out.println("------" + integer);
        });
    }
public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 1000; i++) {
            list.add(i);
        }
        Long startTime = System.currentTimeMillis();
        streamMethod(list);
        Long endTime = System.currentTimeMillis();
        System.out.println("result:" + (endTime - startTime));//116 115 85 84 84
    }

    private static void streamMethod(List<Integer> list) {
        list.stream().forEach(integer -> {
            System.out.println("------" + integer);
        });
    }
public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 1000; i++) {
            list.add(i);
        }
        Long startTime = System.currentTimeMillis();
        parallelStreamMethod(list);
        Long endTime = System.currentTimeMillis();
        System.out.println("result:" + (endTime - startTime)); //179 138 140 122 175
    }

    private static void parallelStreamMethod(List<Integer> list) {
        list.parallelStream().forEach(integer -> {
            System.out.println("------" + integer);
        });
    }

在数据量为1000时,效率依次是for>foreach>stream.foreach>parallelStream.foreach。
理论上,数据量越大,stream的效率越高,parallelStream的效率会最高且是并行处理。但选用需思考其场景,避免数据安全问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是JavaStream的常用方法: 1. filter()方法:根据指定的条件过滤中的元素。 ```java List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); ``` 2. map()方法:将中的每个元素映射为另一个元素。 ```java List<String> names = Arrays.asList("John", "Tom", "Jerry"); List<Integer> nameLengths = names.stream() .map(String::length) .collect(Collectors.toList()); ``` 3. sorted()方法:对中的元素进行排序。 ```java List<Integer> numbers = Arrays.asList(5,3, 1, 4, 2); List<Integer> sortedNumbers = numbers.stream() .sorted() .collect(Collectors.toList()); ``` 4. distinct()方法:去除中的重复元素。 ```java List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 4, 5); List<Integer> distinctNumbers = numbers.stream() .distinct() .collect(Collectors.toList()); ``` 5. limit()方法:限制中元素的数量。 ```java List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> limitedNumbers = numbers.stream() .limit(3) .collect(Collectors.toList()); ``` 6. skip()方法:跳过中的前几个元素。 ```java List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); List<Integer> skippedNumbers = numbers.stream() .skip(2) .collect(Collectors.toList()); ``` 7. forEach()方法:对中的每个元素执行指定的操作。 ```java List<String> names = Arrays.asList("John", "Tom", "Jerry"); names.stream() .forEach(System.out::println); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值