学习Stream的目的
- 函数式编程渐渐变成主流,为了看懂同事的代码。
- 相对于传统的编程方式,代码更为简洁清晰易懂。
- 使得并发编程变得如此简单。
- 有效的避免了代码嵌套地狱。(见样例)
- if (条件1) {
- if (条件2) {
- if (条件3) {
- // 再嵌套下去都快见到Diablo了。
- }
- }
- }
复制代码 Stream的特点
- 不修改数据源:任何对于Stream对象的操作都不会修改数据源的数据。
- 延迟执行:中间操作只是对于一系列操作细节的定义,而非执行。只有在终端操作被调用的同时执行中间操作。
- 可消费:任何一个Stream对象执行了终端操作后都将不可再利用。只能操作由数据源生成的新的Stream。
Stream的分类
- 串行流:单项环境下的Stream,基础。
- 并行流:多线程环境下的Stream,重点难点。本文中未涉及。
- List.of().parallelStream();
复制代码 Stream对象的创建
总共有三种方式:
- 经由集合对象创建
- List<String> list = new ArrayList<>();
- Stream<String> stream = list.stream();
复制代码 - 经由数组对象创建(两种)
- String[] strs = new String[10];
- // 将数组所有元素装入stream
- Stream<String> stream1 = Arrays.stream(strs);
- // 将数组指定区间的元素装入stream
- Stream<String> stream2 = Arrays.stream(strs, 1, 7);
复制代码 - 使用Stream的静态方法创建(三种)
- // 由单个元素创建Stream,元素不允许为null
- Stream<String> stream1 = Stream.of("Test");
- // 由单个元素创建stream,元素允许为null
- Stream<String> stream2 = Stream.ofNullable(null);
- // 由多个元素创建stream,内部其实调用的是Arrays.stream(T[] array)
- Stream<String> stream3 = Stream.of("Test1", "Test2", "Test3");
复制代码 方法的分类
- 中间操作:根据调用的方法,返回各种各样的stream对象。传入的各种Lambda只是修改了该对象中对应方法的定义,而非执行。
- 终端操作:执行终端操作的方法,并且其间也执行中间操作对应的方法。
常用方法(入门)
中间操作
distinct
方法签名:Stream distinct()
作用:返回一个去重后的Stream。- List<String> list = List.of("1", "1");
- list.stream().distinct()
- .forEach(t -> System.out.println(t)); // 输出:1
复制代码 filter
方法签名:Stream filter(Predicate |