串行Stream流和并行Stream流

串/并行Stream流

package com.zenqgifeng.practicedemo.jdk8newproperties;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

/**
 * @author zengqifeng
 * @version 1.0
 * @date 2020/1/3 9:57
 *  基于collect方法
 *      聚合计算    maxBy,minBy,avg..,sum..
 *      分组  group
 *      多级分组
 *      分区  满足条件的分去true区,不满足条件的分去false区
 *      连接   连接符,前缀,后缀
 *  串行stream流和并行stream流
 *      默认创建的就是串行stream流
 *      并行stream流的两种创建方式
 *          1、集合.parale...stream
 *          2.Stream.parale....
 *      串行stream和并行stream的效率对比
 *      并行stream流可能出现线程安全问题体
 *      线程安全问题解决办法
 *          1、sync代码块包裹
 *          2、Vector线程安全类集合
 *          3、Collections.sync(Collection  推荐
 *          4、toArray/collect(Colectors.toList)方法返回操作就是线程安全的
 */
public class Demo05 {

    private static Long times = 500000000L;
    private Long start;
    private Long end;
    private long sum;

    @Before
    public void init() {
        sum = 0L;
        start = System.currentTimeMillis();
    }

    @After
    public void fianl() {
        end = System.currentTimeMillis();
        System.out.println("消耗时间:" + (end - start) + "毫秒");
    }

    /**
     * 聚合计算
     */
    @Test
    public void test1() {
        Stream<Student> stream = Stream.of(
                new Student("张三", 20),
                new Student("李四", 23),
                new Student("王五", 18),
                new Student("赵六", 26)
        );
        //求最大值
        /*Optional<Student> max = stream.collect(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge()));
        System.out.println("max:" + max);*/
        //求最小值
        /*Optional<Student> min = stream.collect(Collectors.minBy((s1, s2) -> s1.getAge() - s2.getAge()));
        System.out.println("min:" + min);*/
        //求和
        /*Integer sum = stream.collect(Collectors.summingInt(Student::getAge));
        System.out.println("sum:" + sum);*/
        //求平均值
        /*Double avg = stream.collect(Collectors.averagingInt(Student::getAge));
        System.out.println("avg:" + avg);*/
        //计数
        Long count = stream.collect(Collectors.counting());
        System.out.println("count:" + count);
    }

    /**
     * 分组
     */
    @Test
    public void test2() {
        Stream<Student> stream = Stream.of(
                new Student("张三", 20, 89),
                new Student("李四", 23, 90),
                new Student("王五", 20 ,50),
                new Student("赵六", 23, 56)
        );
        //根据年龄分组   返回的是啥就根据啥分组
        /*Map<Integer, List<Student>> map = stream.collect(Collectors.groupingBy(Student::getAge));
        map.forEach((k, y) -> {
            System.out.println(k + "::" + y);
        });*/
        //超过60分为及格组
        Map<String, List<Student>> map1 = stream.collect(Collectors.groupingBy((s) -> {
            if (s.getScore() > 60) {
                return "及格";
            } else {
                return "不及格";
            }
        }));
        map1.forEach((x, y) -> {
            System.out.println(x + "::" + y);
        });
    }

    /**
     * 多级分组
     * 先根据年龄分组,再根据score分组
     */
    @Test
    public void test3() {
        Stream<Student> stream = Stream.of(
                new Student("张三", 20, 89),
                new Student("李四", 23, 90),
                new Student("王五", 20 ,50),
                new Student("赵六", 23, 56)
        );

        Map<Integer, Map<String, List<Student>>> map = stream.collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(s -> {
            if (s.getScore() > 60) {
                return "及格";
            } else {
                return "不及格";
            }
        })));

        map.forEach((k1, v1) -> {
            System.out.println(k1);
            v1.forEach((k2, v2) -> {
                System.out.println("\t" + k2 + "::" + v2);
            });
        });
    }

    /**
     * 分区       true  false
     */
    @Test
    public void test4() {
        Stream<Student> stream = Stream.of(
                new Student("张三", 20, 89),
                new Student("李四", 23, 90),
                new Student("王五", 20, 50),
                new Student("赵六", 23, 56)
        );

        Map<Boolean, List<Student>> map = stream.collect(Collectors.partitioningBy(s -> {
            if (s.getScore() > 60) {
                return true;
            } else {
                return false;
            }
        }));

        map.forEach((k, v) -> {
            System.out.println(k + "::" + v);
        });
    }

    /**
     * join  连接
     */
    @Test
    public void test5() {
        Stream<Student> stream = Stream.of(
                new Student("张三", 20, 89),
                new Student("李四", 23, 90),
                new Student("王五", 20, 50),
                new Student("赵六", 23, 56));

        /*String names = stream.map(Student::getName).collect(Collectors.joining("-"));
        System.out.println(names);*/

        String names1 = stream.map(Student::getName).collect(Collectors.joining("-", "^_^", "V_V"));
        System.out.println(names1);
    }

    /**
     * 串行流和并行流
     * 默认获取的就是串行流
     *
     * 并行流的获取方式
     * list.parallel()
     * Stream.parallel
     */
    @Test
    public void test6() {
        Stream<Student> stream = Stream.of(
                new Student("张三", 20, 89),
                new Student("李四", 23, 90),
                new Student("王五", 20, 50),
                new Student("赵六", 23, 56));

        /*long count = stream.filter(s -> {
            System.out.println(Thread.currentThread().getId() + ":" + s.getAge());
            return s.getScore() > 60;
        }).count();*/

        /*Stream<Student> parallel = stream.parallel();
        long count = stream.filter(s -> {
            System.out.println(Thread.currentThread().getId() + ":" + s.getAge());
            return s.getScore() > 60;
        }).count();*/

        List<Student> list = new ArrayList<>();
        Collections.addAll(list,new Student("张三", 20, 89),
                new Student("李四", 23, 90),
                new Student("王五", 20, 50),
                new Student("赵六", 23, 56));

        Stream<Student> studentStream = list.parallelStream();
        long count = studentStream.filter(s -> {
            System.out.println(Thread.currentThread().getId() + ":" + s.getAge());
            return s.getScore() > 60;
        }).count();
        System.out.println(count);
    }

    /**
     * 测试串行并行stream 普通之间的效率
     * 当操作的数据量较大时使用并行stream效率明显高些
     */
    @Test
    public void testParallel() {
        //消耗时间:1784毫秒
        /*for (Long i = 0L; i < times; i++) {
            sum += i;
        }*/

        //消耗时间:247毫秒
        /*LongStream.rangeClosed(0, times).reduce(0, Long::sum);*/

        //消耗时间:127毫秒
        /*LongStream.rangeClosed(0, times).parallel().reduce(0, Long::sum);*/
        LongStream.rangeClosed(0, times).parallel().reduce(0L, Long::sum);
    }

    /**
     * 并行stream,线程安全问题
     */
    @Test
    public void testParallelSaveQuestion() {
        //并行stream    可能出现线程安全问题
        /*List<Integer> list = new ArrayList<>();
        IntStream.rangeClosed(1, 1000).parallel().forEach(n -> {
            list.add(n);
        });*/
        /*System.out.println(list.size());*/
        //线程安全问题解决办法
        //1、sync        同步代码块
        /*List<Integer> newList = new ArrayList<>();
        IntStream.rangeClosed(1, 1000).parallel().forEach(n -> {
            //注意包裹范围,包裹可能出现线程安全的语句,范围不能大
            synchronized (newList) {
                newList.add(n);
            }
        });*/
        //2、使用Vector
        //3、使用Collections.sync....
        /*List<Integer> list = new ArrayList<>();
        //底层使用的是  CPU的 CAS指令  意思是比较再交换   效率高还好用   推荐
        List<Integer> newList = Collections.synchronizedList(list);
        IntStream.rangeClosed(1, 1000).parallel().forEach(n -> {
                newList.add(n);
        });*/
        //4、调用stream流的toArray、collect方法就变成线程安全了
        //IntStream     LongStream等对应基本数据类型的流    消耗内存小且节省装箱拆箱时间
        //自然这种流对应的功能也少些,比如它的collect方法就只有一种,需要装箱才能调用多种collect方法
        List<Integer> newList = new ArrayList<>();
        IntStream.rangeClosed(1, 1000).parallel().boxed().collect(Collectors.toCollection(ArrayList::new)).forEach(n -> {
            newList.add(n);
        });

        System.out.println(newList.size());
    }

}


class Student{
    private String name;
    private Integer age;
    private Integer score;

    public Student() {
    }



    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    public Student(String name, Integer age, Integer score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值