Stream介绍

在JDK1.8,Collection 接口新增了 stream 方法,用于构建 Stream 对象,从而进行一系列对集合的操作。

  • stream 是一个元素的序列,它支持串行与并行的聚合操作;
  • stream 本身不存储值,它通过管道(AbstractPipeline)的方式获取值;
  • stream 本质是函数式的,对流的操作会生成一个结果,不过并不会修改底层的数据源,集合可以作为流的底层数据源;
  • stream 可以设置延迟查找特性,很多流操作(过滤、映射、排序等)都可以延迟实现;
  • stream 由 数据源、零个或多个中间操作、终止操作 构成
  • stream 的链式操作特性:若最后没有添加终止操作,中间所定义的操作都不会执行;当调用终止操作时,流即会输出结果
  • stream 的特性
    • 流每进行一次中间操作,都会生成一个全新的流;
    • 不能对同一个流进行多次操作,否则会抛出异常;
    • 流的所有中间操作在遇到终止操作时,即会对集合进行遍历,同时将中间操作的内容作用于遍历过程,因此流的操作最终只进行了一次遍历操作

stream 的常用方法

  • map(Function<? super T, ? extends R> mapper):中间操作,
    • 对 steam 中的可用元素进行指定的操作
    • mapToInt(ToIntFunction<? super T> mapper):map 方法的原生特化版本,其他还有 mapToDouble 和 mapToLong
  • flatMap(Function<? super T, ? extends Stream<? extends R>> mapper):
    • 中间操作,将遍历的集合中的元素转化为 stream,然后将这些 stream 进行汇聚合并
  • filter(Predicate<? super T> predicate):
    • 中间操作,用于判断过滤指定元素
  • limit(long maxSize):
    • 短路中间操作,用于限定流中元素的个数
  • skip(long n):
    • 短路中间操作,用于跳过流中指定个数的元素
  • findFirst():
    • 短路终止操作,获取 stream 中第一个参数,返回一个 Optional(由于数据源中元素个数未知)
  • sum():
    • IntStream 中的方法,求和,元素个数为0则返回0
  • min() / max() / ...:
    • IntStream 中的方法,求最大最小值...,返回 OptionalInt

流的本质:内部迭代与外部迭代

  • 外部迭代:集合的处理,集合关注的是数据与数据储存本身
  • 内部迭代:流的处理,流关注的是对数据的计算
  • 注意点:流的内部是存在短路运算的

举例

例子1

学生 A、B 只定义了name和age,图中A与B均使出影分身,分裂成A1、A2 与B1、B2,然后打印出来

public class StreamTest1 {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student("A", 1));
        list.add(new Student("B", 2));

        list.stream().map(student -> {
            List<Student> innerList = new ArrayList<>();
            innerList.add(new Student(student.getName() + "1", student.getAge()));
            innerList.add(new Student(student.getName() + "2", student.getAge()));
            return innerList;
        }).flatMap(List::stream).forEach(System.out::println);
    }
}

例子2

给出一组字符串:"hello welcome", "hello world", "hello world hello", "hello welcome"

要求:切割空格得出所有英文单词,去重复后打印出来

public class StreamTest2 {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("hello welcome", "hello world", "hello world hello", "hello welcome");
        list.stream().map(word -> word.split(" ")).flatMap(Arrays::stream).distinct().forEach(System.out::println);
    }
}

 

posted @ 2019-09-14 15:50  飞蛇在水  阅读(708)  评论(0编辑  收藏  举报