揭秘 Java Stream 的使用密码
典型回答
- Stream 提供一种直观方式对 Java 集合运算和表达的高阶抽象。
- Stream API 可以极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如 筛选,排序,聚合等。
Stream 特点:
-
无存储。
Stream 只是某种数据源的一个视图,数据源可以是一个数组、Java容器、 I/O channel 等。
-
为函数式编程而生。
对 Stream 的任何修改都不会修改背后的数据源。
-
惰式执行。
Stream 上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
-
可消费性。Stream 只能被“消费”一次,一旦遍历过就会失效。
最佳实践(推荐)
- 对于 简单操作,使用外部迭代手动实现
- 对于 复杂操作,推荐使用 Stream API
- 多核情况下,推荐使用并行 Stream API 来发挥多核优势;
- 单核情况下,不建议使用并行 StreamAPI。
- 当数据量比较小的情况,没必要用并行流。
Stream 实践
1. Stream 创建
-
通过已有的集合来创建流
-
class TestStream { public static void main(String[] argv) { List<Integer> list = new ArrayList<>(Arrays.asList(33, 22, 44)); list.stream().forEach(System.out::println); } }
-
-
通过 Stream 创建流
-
class TestStream { public static void main(String[] argv) { Stream s = Stream.of(11, 33, 22); s.forEach(System.out::println); } }
-
2. Stream 中间操作
- Stream 有很多中间操作,多个中间操作可以连接起来形成一个流水线,每一个中间操作就像流水线上的一个工人,每人工人都可以对流进行加工,加工后得到的结果还是一个流。
- Stream 常见的中间操作
filter通过设置过滤条件,过滤出元素
map映射每个元素对应的结果
limit限制只要前几个元素;skip跳过前面几个元素
sorted排序
distinct去重
3. Stream 最终操作
- 最终操作会消耗流,产生一个最终结果。否则,会抛出异常
java.lang.IlegalstateException: stream has already been operated upon or closed。 - 常用的最终操作
forEach迭代输出
count计数
collect是一个归约操作,将流中的元素汇积总一具结果。