1.Stream并行流的使用方式

 1. stream().parallel()
     先将集合Collection转换成Stream流的形式,再将流转换为并行流
 2. parallelStream()
     直接将Colletion集合转换为并行流

stream().parallel() 和 parallelStream()两种获取并行流 并且执行任务的时间消耗相差无几 可以忽略不计

2.并行流使用注意!!

  1. 并行流的操作大多用来处理一些cpu密集型任务,也就是说多数用来处理计算任务,而不是io任务,io任务一半交由线程层池来完成,因为线程池在执行任务时,并不会阻塞当前调用线程,而并行流却是在调用线程中执行的,在并行流中执行io操作会导致调用线程被阻塞,知道io任务结束
  2. 并行流一般用于执行计算任务,如果涉及到需要使用共享可变的参数,还需要考虑线程安全的问题

3.使用Stream和for循环的区别

我们在需要对某一列表进行遍历时大多有两种方式,一种是for循环,另外一种就是stream,但是在使用他们时,有什么区别呢

  @Test
    public void parallelStreamTest() {
        List<String> lessStringList = generateRandomString(10000);
        List<String> moreStringList = generateRandomString(40000);

        long forStart = System.currentTimeMillis();
        List<String> strings = forMethod(moreStringList, lessStringList);
        long forEnd = System.currentTimeMillis();
        System.out.println("for 循环耗时:" + (forEnd - forStart) + " ms");

        long streamStart = System.currentTimeMillis();
        List<String> streamStrList= streamMethod(moreStringList, lessStringList);
        long streamEnd = System.currentTimeMillis();
        System.out.println("stream 循环耗时:" + (streamEnd - streamStart) + " ms");


        long parallelStreamStart = System.currentTimeMillis();
        List<String> parallelStreamStrList= parallelStreamMethod(moreStringList, lessStringList);
        long parallelStreamEnd = System.currentTimeMillis();
        System.out.println("parallelStream 循环耗时:" + (parallelStreamEnd - parallelStreamStart) + " ms");


        long streamParallelStart = System.currentTimeMillis();
        List<String> streamParallelStrList= streamParallelMethod(moreStringList, lessStringList);
        long streamParallelEnd = System.currentTimeMillis();
        System.out.println("streamParallel 循环耗时:" + (streamParallelEnd - streamParallelStart) + " ms");
    }

    private List<String> forMethod(List<String> moreStringList, List<String> lessStringList) {
        List<String> addList = new ArrayList<>();
        for (String productCode : moreStringList) {
            boolean exist = false;
            for (String str : lessStringList) {
                if (productCode.equals(str)) {
                    exist = true;
                    break;
                }
            }
            if (!exist) {
                addList.add(productCode);
            }
        }
        return addList;
    }

    /*
    使用stream在处理这种简单循环时 可能比普通for循环花费的时间更多
    ,因为使用stream 会造成一些额外的流处理的开销
     */
    private List<String> streamMethod(List<String> moreStringList, List<String> lessStringList) {
        return moreStringList.stream().filter(more -> lessStringList.stream()
                        .noneMatch(less -> less.equals(more)))
                .collect(Collectors.toList());
    }

    private List<String> parallelStreamMethod(List<String> moreStringList, List<String> lessStringList) {
        return moreStringList.parallelStream().filter(more -> lessStringList.stream()
                        .noneMatch(less -> less.equals(more)))
                .collect(Collectors.toList());
    }

    private List<String> streamParallelMethod(List<String> moreStringList, List<String> lessStringList) {
        return moreStringList.stream().parallel().filter(more -> lessStringList.stream()
                        .noneMatch(less -> less.equals(more)))
                .collect(Collectors.toList());
    }

    public static List<String> generateRandomString(int size) {
        List<String> list = new ArrayList<>();
        String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        for (int j = 0; j < size; j++) {
            Random random = new Random();
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < 10; i++) {
                int randomIndex = random.nextInt(CHARACTERS.length());
                char randomChar = CHARACTERS.charAt(randomIndex);
                stringBuilder.append(randomChar);
            }
            list.add(stringBuilder.toString());
        }
        return list;
    }

由上述代码自行测试可知,有时候stream这种看起来高大上的东西在进行一些简单的循环操作时,还不如for循环来的效率高,这是因为使用stream的方法前要先将我们的列表转换成流的形式,造成额外的开销,因此建议,在进行一些简单操作时,推荐使用for循环来完成,有时使用stream并不会提升效率,相反还会降低效率,增加额外开销

最后修改:2024 年 02 月 27 日
如果觉得我的文章对你有用,请随意赞赏