Java8中的Stream - 从例子出发感受

Java8中的Stream - 从例子出发感受,第1张

PS:本文需要对Java8的函数式编程有一定了解
申明:该例子取自B站UP主(噼哩啪啦piapiapia)发布的webFulx响应式编程教程视频:
视频点击直达

Stream的创建
public class CreateStream {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("!11");
        // 从集合中创建
        final Stream<String> stream = list.stream();
        // 并发流
        final Stream<String> stringStream = list.parallelStream();

        // 从数组
        final IntStream stream1 = Arrays.stream(new int[]{2, 4, 5});

        // 创建数字流
        final IntStream intStream = IntStream.of(1, 2, 3);
        final IntStream intStream1 = IntStream.rangeClosed(1, 10);

        // 使用random创建无限流  random的流是无线的 所以最好添加limit,不然会报错
        final IntStream limit = new Random().ints().limit(10);

        final Random random = new Random();
        // 自己生成刘
        final Stream<Integer> limit1 = Stream.generate(random::nextInt).limit(20);

    }
}
Stream流 *** 作
public class StreamDemo1 {
    public static void main(String[] args) {
        String str = "my name is 007";

        // 把长度大于2的单词的长度输出
        Stream.of(str.split(" "))
                .map(String::length)
                .filter(length -> length > 2)
                .forEach(System.out::println);

        // flatMap A->B属性(是个集合),最终得到所有A元素里面的所有B属性集合
        // 场景 A 里面有一个 List B
        // intStream/longStream不是Stream的子类,所以用boxed进行装箱
        Stream.of(str.split(" ")).flatMap(s -> s.chars().boxed())
                .forEach(i -> System.out.println((char) i.intValue()));

        // peek 用于 debug,是个中间 *** 作 而forEach是终止 *** 作
        Stream.of(str.split(" "))
                .peek(System.out::println)
                .forEach(System.out::println);

        // limit
        new Random().ints()
                .filter(i -> i > 100 && i < 1000)
                .limit(10)
                .forEach(System.out::println);
    }
}
Stream终止 *** 作
public class StreamDemo2 {
    public static void main(String[] args) {
        String str = "my name is 007";
        // forEach /  forEachOrdered
        // 结果 0a m0 eysn 7im
        str.chars().parallel().forEach(i -> System.out.print((char) i));
        // 结果  my name is 007
        str.chars().parallel().forEachOrdered(i -> System.out.print((char) i));

        // collect/Array
        List<String> collect = Stream.of(str.split(" "))
                .collect(Collectors.toList());

        //reduce 拼接字符串  my|name|is|007
        Optional<String> reduce = Stream.of(str.split(" "))
                .reduce((s1, s2) -> s1 + "|" + s2);
        System.out.println(reduce.orElse(""));
        // 带初始值 结果 |my|name|is|007
        String reduce2 = Stream.of(str.split(" "))
                .reduce("", (s1, s2) -> s1 + "|" + s2);
        System.out.println(reduce2);

        // 计算总长度 初始值为0
        Integer reduce3 = Stream.of(str.split(" "))
                .map(String::length)
                .reduce(0, (s1, s2) -> s1 + s2);
        System.out.println(reduce3);

        // max 根据Comparator comparator 排序 求出最大值
        // 这里结果是my 长度最小  这个和 max里面的函数有关
        Optional<String> max = Stream.of(str.split(" "))
                .max((s1, s2) -> s2.length() - s1.length());
        System.out.println(max);

        // 短路 *** 作
        final OptionalInt first = new Random().ints().findFirst();
        System.out.println(first.getAsInt());

    }
}
Stream并行流
public class StreamDemo3 {
    public static void main(String[] args) {
        // 按顺序执行 1 2 3 4
        long count = IntStream.range(1, 6).peek(StreamDemo3::debug).count();
        
        // 并发流 不按顺序并发执行 7 2 9 3
        // PS:在控制台中我们发现 并行用的是系统默认的线程池ForkJoinPool.commonPool
        // 默认情况下线程池有和CPU个数一样的线程
        // 通过 System.setProperty() 可以设置线程池数量
        System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "20");
        long count2 = IntStream.range(1, 100).parallel().peek(StreamDemo3::debug).count();

        // 先并行再串行
        // idea : 使用parallel 进行并行 然后使用sequential对上一步的 *** 作进行串行执行
        // 结论: 在多次调用 parallel / sequential 情况下以最后一次调用为准
        long count3 = IntStream.range(1, 6)
                .parallel().peek(StreamDemo3::debug)
                .sequential().peek(StreamDemo3::debug2)
                .count();

        // 使用自定义线程池,防止任务被阻塞
        ForkJoinPool pool = new ForkJoinPool(20);
        pool.submit(() -> IntStream.range(1, 100).parallel()
                .peek(StreamDemo3::debug)
                .count());
        pool.shutdown();

        synchronized (pool) {
            try {
                pool.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    private static void debug(int i) {
        System.out.println(Thread.currentThread().getName() + " debug - " + i);
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static void debug2(int i) {
        System.out.println(Thread.currentThread().getName() + " debug2 - " + i);
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
收集器
public class StreamDemo4 {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
                new Student("小明", 10, Gender.MALE, Grade.ONE),
                new Student("大明", 9, Gender.FEMALE, Grade.FOUR),
                new Student("小白", 8, Gender.MALE, Grade.ONE),
                new Student("小黑", 13, Gender.MALE, Grade.TWO),
                new Student("小红", 7, Gender.FEMALE, Grade.THREE),
                new Student("小黄", 20, Gender.MALE, Grade.ONE),
                new Student("小青", 40, Gender.FEMALE, Grade.TWO),
                new Student("小紫", 60, Gender.FEMALE, Grade.TWO),
                new Student("小王", 54, Gender.MALE, Grade.ONE),
                new Student("小李", 50, Gender.MALE, Grade.THREE),
                new Student("小马", 8, Gender.FEMALE, Grade.FOUR),
                new Student("小刘", 10, Gender.MALE, Grade.ONE)
        );
        // 得到所有学生的年龄列表
        final List<Integer> collect = students.stream()
                // 使用方法引用可以减少生成匿名函数
                .map(Student::getAge)
                .collect(Collectors.toList());
        System.out.println(collect);

        // 统计汇总信息
        final IntSummaryStatistics collect1 = students.stream()
                .collect(Collectors.summarizingInt(Student::getAge));
        System.out.println(collect1);

        // 分块
        // 根据条件分两块
        final Map<Boolean, List<Student>> collect2 = students.stream()
                .collect(Collectors.partitioningBy(s -> s.getGender() == Gender.MALE));
        System.out.println(collect2);

        // 分组(比分块更灵活)
        final Map<Grade, List<Student>> collect3 = students.stream()
                .collect(Collectors.groupingBy(Student::getGrade));
        System.out.println(collect3);

        // 得到所有班级学生的个数
        final Map<Grade, Long> collect4 = students.stream()
                .collect(Collectors.groupingBy(Student::getGrade, Collectors.counting()));
        System.out.println(collect4);
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/939624.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-17
下一篇 2022-05-17

发表评论

登录后才能评论

评论列表(0条)

保存