Stream

239 阅读4分钟

概述

Stream 的操作三个步骤

  • 创建 Stream 一个数据源(如:集合、数组),获取一个流
  • 中间操作 一个中间操作链,对数据源的数据进行处理
  • 终止操作(终端操作) 一个终止操作,执行中间操作链,并产生结果

1.Stream创建

package jdk.jdk8.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;

/**
 * Stream
 *  Stream不会自己存储数据
 *  Stream不会改变源数据,会返回一个持有结果的新的stream
 *  Stram是延时操作
 *
 *
 *
 *
 */
public class StreamDemo {

    public static void main(String[] args) {

        //Stream的创建方式
        //1.collection提供的stream()方法或parallelStream()方法
        ArrayList<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();
        Stream<String> stringStream = list.parallelStream();

        //2.Arrays的静态方法stream()
        Stream<Person> stream1 = Arrays.stream(new Person[10]);

        //3.Stream类的静态方法of()
        Stream<String> aaa = Stream.of("aaa", "bbb", "ccc");

        //4.无限流
            //迭代
        Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2);
            //选择
        Stream<Integer> generate = Stream.generate(() -> 1);

    }
}
class Person{

}

2.中间操作

多个中间操作可以连接起来形成一个流水线,除非流水 线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为“惰性求值”。

筛选与切片

方 法 描 述
filter(Predicate p) 接收 Lambda , 从流中排除某些元素。
distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去 除重复元素
limit(long maxSize) 截断流,使其元素不超过给定数量。
skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素 不足 n 个,则返回一个空流。与 limit(n) 互补
package jdk.jdk8.stream;

import java.util.Objects;

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}




package jdk.jdk8.stream;

import java.util.ArrayList;

public class StreamDemo2 {

    public static void main(String[] args) {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("zhangsan",10));
        list.add(new Person("lisi",20));
        list.add(new Person("wangwu",30));
        list.add(new Person("zhaoliu",40));
        list.add(new Person("tianqi",50));
        list.add(new Person("tianqi",50));
        list.add(new Person("tianqi",50));

        //filter(Predicate p) 接收 Lambda , 从流中排除某些元素。
        list.stream().filter((person)->{
            System.out.println("Streeam Filter...");
            return person.getAge()>20;
        }).forEach(System.out::println);

        System.out.println("-------------------------------------------------------------");

        //distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去 除重复元素
        list.stream().filter((person)->{
            System.out.println("Streeam Filter...");
            return person.getAge()>20;
        }).distinct().forEach(System.out::println);

        System.out.println("-------------------------------------------------------------");

        //limit(long maxSize) 截断流,使其元素不超过给定数量。
        list.stream().filter((person)->{
            System.out.println("Streeam Filter...");
            return person.getAge()>20;
        }).limit(2).forEach(System.out::println);

        System.out.println("-------------------------------------------------------------");

        //skip(long n)
        list.stream().filter((person)->{
            System.out.println("Streeam Filter...");
            return person.getAge()>20;
        }).skip(2).forEach(System.out::println);



    }
}



Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='wangwu', age=30}
Streeam Filter...
Person{name='zhaoliu', age=40}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}
-------------------------------------------------------------
Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='wangwu', age=30}
Streeam Filter...
Person{name='zhaoliu', age=40}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Streeam Filter...
-------------------------------------------------------------
Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='wangwu', age=30}
Streeam Filter...
Person{name='zhaoliu', age=40}
-------------------------------------------------------------
Streeam Filter...
Streeam Filter...
Streeam Filter...
Streeam Filter...
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}
Streeam Filter...
Person{name='tianqi', age=50}

映射

方 法 描 述
map(Function f) 接收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素。
mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 DoubleStream。 mapToInt(ToIntFunction f)
flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另 一个流,然后把所有流连接成一个流

排序

方 法 描 述
sorted() 产生一个新流,其中按自然顺序排序
sorted(Comparator comp) 产生一个新流,其中按比较器顺序排序

3.Stream 的终止操作

终端操作会从流的流水线生成结果。其结果可以是任何不是流的 值,例如:List、Integer,甚至是 void 。

查找与匹配

方 法 描 述
allMatch(Predicate p) 检查是否匹配所有元素
anyMatch(Predicate p) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
count() 返回流中元素总数
max(Comparator c) 返回流中最大值
min(Comparator c) 返回流中最小值
forEach(Consumer c) 内部迭代(使用 Collection 接口需要用户去做迭 代,称为外部迭代。相反,Stream API 使用内部 迭代——它帮你把迭代做了)

归约

方 法 描 述
reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 T 归约
reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。 返回 Optional
collect(Collector c) 将流转换为其他形式。接收一个 Collector接口的 实现,用于给Stream中元素做汇总的方法

Collector 接口中方法的实现决定了如何对流执行收集操作(如收 集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态 方法,可以方便地创建常见收集器实例,具体方法与实例如下表: