您当前的位置: 首页 >  Java

Charge8

暂无认证

  • 1浏览

    0关注

    447博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java8 Stream API详细操作

Charge8 发布时间:2020-09-02 15:29:07 ,浏览量:1

一、Stream流的基本概念

1、什么是Stream流?

流是Java8引入的全新概念,它用来处理集合中的数据,对集合(Collection)对象功能的增强,专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。

Java中的Stream并不会存储元素,而是按需计算,且只能遍历一次。同时结合 Lambda 表达式,极大的提高编程效率和程序可读性。

Stream流采用内部迭代方式,通过访问者模式(Visitor)实现。

若要对集合进行处理,则需我们手写处理代码,这就叫做外部迭代。比如:使用Iterator或for循环来遍历集合。

若要对流进行处理,我们只需告诉流我们需要什么结果,处理过程由流自行完成,这就称为内部迭代。比如:Collection.forEach(…)方法迭代。

2、Stream流的操作种类

流的操作可以分为两种:中间操作和终端操作。

1. 中间操作

当数据源中的数据上了流水线后,这个过程对数据进行的所有操作都称为中间(intermediate)操作。 

中间操作可以连接起来,将一个流转换为另一个流。这样多个操作可以串联成一个管道(Pipelining), 如同流式风格(fluent style)。

中间操作都会返回流对象本身。

2. 终端操作 

当所有的中间操作完成后,若要将数据从流水线上拿下来,则需要执行终端(Terminal )操作。 

一个流只能有一个终端操作,当这个操作执行后,流的操作就结束了,无法再被操作。

Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果。

3、Stream流的操作过程

Stream流操作可以分三个步骤:

1、获取一个数据源:可以是集合,数组,I/O channel, 产生器generator 等。

2、中间操作(intermediate operation):

      在管道的节点上进行处理,比如: filter、 distinct、 sorted等,它们可以串连起来形成流水线。

3、最终操作( terminal operation):执行终端操作后本次流结束,并返回一个执行结果。

      注意:流进行了终止操作后,不能再次使用,否则会报错。

二、获取Stream流对象

在使用流之前,需要先拥有一个数据源,并通过 StreamAPI提供的一些方法获取该数据源的 Stearm接口类型流对象。

注意:

  • 除了Stream类型外,还有几个IntStream、LongStream、DoubleStream很常用, 因为boxing 和 unboxing 会很耗时,所以特别为这三种基本数值型提供了对应的 Stream。
  • 此外还有一个流类型:并行流parallelStream,parallelStream提供了流的并行处理,它是Stream的另一重要特性,其底层使用Fork/Join框架实现。

串行流:适合存在线程安全问题、阻塞任务、重量级任务,以及需要使用同一事务的逻辑。

Stearm类型有:Stream,还有IntStream、LongStream、DoubleStream也很常用,因 boxing和 unboxing会很耗时,所以,这三种基本数值型提供了对应的 Stream。

并行流:流的并行处理,适合没有线程安全问题、较单纯的数据处理任务。

Stearm类型有:并行流parallelStream。

其中 parallelStream()方法能够充分利用多核 CPU的优势,使用多线程加快对集合数据的处理速度。

下面来认识常用的数据源来获取 Stearm对象。后面进行操作的更多方法等,请查看API。

public class User {
    private int id;
    private String name;
    private String sex;
    private int age;
    private int height;
...
}

1、集合 

集合 数据源比较为常用,通过 stream()方法即可获取 Stearm对象。

        List list = new ArrayList();
        list.add(new User(1, "赵云", "男", 18, 178));
        list.add(new User(2, "后裔", "男", 20, 188));
        list.add(new User(1, "妲己", "女", 17, 175));

        Stream stream = list.stream();
        Stream parallelStream = list.parallelStream();

2、数组 

通过 Arrays 类提供的静态 stream()方法获取数组的 Stearm对象。

        String[] arr = new String[]{"赵云", "后裔", "妲己"};
        Stream stream = Arrays.stream(arr);

3、值 

直接将几个值变成 Stearm对象,IntStream、LongStream、DoubleStream。

        IntStream intStream = IntStream.of(new int[]{1, 2, 3});
        LongStream longStream = LongStream.range(1, 3); // [1,3)
        LongStream longStream2 = LongStream.rangeClosed(1, 3); // [1,3]
        DoubleStream doubleStream = DoubleStream.of(1.0, 3.0); 

4、其他创建方法

    • static  Streamgenerate(Supplier s)

      返回一个无穷序列无序流,其中每个元素是由提供 Supplier生成。

      static  Streamiterate(T seed, UnaryOperator f)

      返回一个无穷序列有序 Stream由最初的一元 seed函数的 f迭代应用产生的,产生一个由 seedf(seed)f(f(seed)) Stream,等。

Stream中的 generate() 很好理解。

iterate () 方法,参数为一个种子值,和一个一元操作符(例如 f)。然后种子值成为 Stream 的第一个元素,f(seed) 为第二个,f(f(seed)) 第三个,以此类推。

注意:这两种方法创建的流是无限的,在管道中,必须利用 limit 之类的操作限制 Stream 大小。

        // 生成 10 个随机整数
        Stream stream = Stream.generate(new Random()::nextInt).limit(10);
        // 生成10个等差(2)数列
        Stream stream1 = Stream.iterate(0, n -> n + 2).limit(10);

三、中间操作

1、filter方法:过滤掉不符合谓词判断的数据

    • Streamfilter(Predicate
关注
打赏
1664721914
查看更多评论
0.0411s