Java Stream API | Parallel Stream

Stream API的介绍

Stream API 的出现显著提升了Java对函数式编程的支持,允许开发人员使用声明式的方式处理数据集合,例如列表、数组等。同时还能有效的使用多核处理器进行并行操作,提升应用程序的性能,代码更加简洁。

为什么要引入Stream API

我们在pojo包下创建一个Person实体

    private String name;
    private int age;
    private String country

并在主入口处创建一个Person类型的List

        List<Person> people = Arrays.asList(
                new Person("Noe", 45, "USA"),
                new Person("Stan", 12, "JPA"),
                new Person("Noe", 45, "USA"),
                new Person("Stan", 12, "JPA"),
                new Person("Grace", 5, "UK"),
                new Person("Alex", 18, "USA"),
                new Person("Albert", 91, "FR")
        );

如果我们要从people中取出age大于18的人员应该怎么做呢?
常规方法是我们设置一个循环遍历people中的每一个元素在去判断它们的age

        List<Person> adults = new ArrayList<>();
        for (Person person : people) {
   
            if(person.getAge()>18)
            {
   
                adults.add(person);
            }
        }
        System.out.println(adults);
    }

这种方式虽然直观,但是当操作变得复杂时,代码就会变得冗余,难以维护。有没有更加简洁的方式去实现呢,那就是使用Stream API:

        List<Person> adults = people.stream()
                .filter(person -> person.getAge() > 18)
                .collect(Collectors.toList());
        System.out.println(adults);

我们发现当我们使用Stream API后代码变得更加的简洁方便。值得一提的是Stream本身不是一种数据结构,它不会存储数据或改变数据源,他只定义对数据的处理方式。

流的操作

想要熟练掌握Stream API ,关键在于三个核心步骤:

在这里插入图片描述

创建流:可以通过集合、数组、I/O通道等方式创建流。例如,可以通过Collection.stream() 方法将集合转换为流,或者通过Files.lines()方法将文件的每一行作为流的元素。

中间操作:对流进行中间操作,可以对流进行过滤、映射、排序等操作,以生成一个新的流。中间操作是惰性的,只有当执行终端操作时,中间操作才会被触发执行。

终端操作:对流进行终端操作,可以对流进行计算、收集结果、打印输出等操作。终端操作会触发流的处理,产生最终的结果。常见的终端操作包括forEach()count()、**collect()**等。

值得注意的是,执行终端操作后,流就被消费掉不能再使用。

创建流

创建流的方式有很多,对于实现了Collection接口的集合,都可以通过Stream()方法直接创建Stream流。下面展示List、数组直接通过Stream()方法创建流:

        List<String> list = Arrays.asList("a", "b", "c");
        Stream<String> stream = list.stream();
        stream.forEach(System.out::println);


        String[] array = {
   "a", "b", "c"};
        Stream<String> stream = Arrays.stream(array);
        stream.forEach(System.out::println);

通过Stream.of方法直接创建流:

IntStream intStream = IntStream.of(1, 2, 3);

合并两个流:

        Stream<String> stream1 = Stream.of("a", "b", "c");
        Stream<String> stream2 = Stream.of("d", "e", "f");

        Stream<String> concat = Stream.concat(stream1, stream2);
        concat.forEach(System.out::println);

通过Stream.builder() 创建流:

        Stream.Builder<String> builder = Stream.builder();
        builder.add("a");
        builder.add("b");
        if(Math.random()>0.5)
        {
   
            builder.add("c");
        }
        Stream<String> stream = builder.build();
        ///调用build就不能再add
        stream.forEach(System.out::println);

文件创建流,通过Java的files类的lines方法实现。
首先我们拿到文件的路径,在进行lines方法时他会逐行读取文件的内容,每一行文本都会被当成一行字符串处理。
需要注意,通过此方式打开的文件需要进行妥善关闭,所以下述代码进行了try with resource操作。

        Path path = Paths.get("file.txt");
        try(Stream<String> lines = Files.lines(path)) {
   
            lines.forEach(System.out::println);
        } catch (IOException e) {
   
            e.getStackTrace();
        }

对基本数据类型 StreamAPI 提供了IntStreamLongStreamDoubleStream。通过使用range()rangeClosed 等方法可以和方便的创建这些类型的流。range 左闭右开、rangeClosed 左闭右闭。也可以使用基本类型流转化为对象流通过boxed()方法。

//        IntStream intStream = IntStream.range(0,4);
        IntStream intStream = IntStream.rangeClosed(0,4);
        Stream<Integer> boxed = intStream.boxed();
        boxed.forEach(System.out::println);

创建无限流,使用Stream的generate方法创建,通过limit来限制创建的个数。

        Stream<String> stringStream = Stream.generate(() -> "Mizuki").limit(5);
        stringStream.forEach(System.out::println);
        Stream.generate(Math::random).limit(5).forEach(System.out::println);

通过Streamiterate方法可以实现生成数学序列或者迭代算法,下述代码实现一个起始为 0 的有界等差数列:

 Stream.iterate(0,n->n+2).limit(10).forEach(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值