Java 8 | Stream 简介与常用方法

2017-07-31 From 程序之心 By 丁仪

Stream 是什么

在介绍 Stream 之前,先回顾一下以往的集合操作。比如对于一个 list,需要统计其中大于 3 的数字,可能会使用迭代器写出如下的代码遍历 list 进行统计。

List<Integer> list = Arrays.asList(1,2,3,4,5); 
Iterator<Integer> iterator = list.iterator(); 
int countBigThan3 = 0; 
while (iterator.hasNext()) {
  Integer value = (Integer) iterator.next();
  if(value > 3) countBigThan3 ++; 
}

这种传统的迭代操作被称为外部迭代,也就是说,迭代的过程在集合之外。外部迭代的过程可以简单表示成下图,迭代中应用代码与集合代码有大量交互,使得应用代码在表达自身逻辑之外还需要大量引用集合代码。

Java 8 为我们带来了 Stream。Stream 是用函数式编程方式在集合类上进行复杂操作的工具。上面的统计代码可以基于 Stream 改写成如下代码。可以看到,代码中几乎只有比较和统计操作,代码简单,逻辑清晰。其中,filter 方法传入了一个 lambda 表达式用于筛选大于 3 的数字,count 方法统计了筛选过数字的个数。

List<Integer> list = Arrays.asList(1,2,3,4,5); 
long countBigThan3 = list.stream() .filter(value -> value > 3) .count();

Stream 的这种迭代操作被称为内部迭代。应用代码通过 Stream 构建迭代的逻辑,然后在集合代码中完成迭代,应用代码只需要迭代后获取结果即可。在上面的代码中,filter 方法描述了 Stream 的操作但并不立即执行,这样的方法被称为惰性求值方法,而 count 方法从 Stream 中获取结果,这样的方法被称为及早求值方法。

collect 方法

collect 方法由 Stream 里的值生成一个列表,是一个及早求值方法。在下面的代码中,使用 of 方法初始化了一个 Stream,然后用 collect 方法生成了一个列表,列表中的元素即是 Stream 中的值。

List<String> lowerList = Stream.of("a","b","c") .collect(Collectors.toList());

map 方法

map 方法是一个惰性求值方法,用于把 Stream 中的值替换为新的值。map 方法接受一个 lambda 表达式,而且必须是 Function 接口的实现。Function 接口的参数类型对应旧值的类型,返回值类型对应新值的类型,这两个类型可以是不同的类型。

List<String> upperList = Stream.of("a","b","c") .map(value -> value.toUpperCase()) .collect(Collectors.toList());

filter 方法

filter 方法用于过滤 Stream 中的值,接受一个 lambda 表达式,而且必须是 Predicate 接口的实现。Predicate 接口定义了一个 test 抽象方法,返回 true 的参数会被放入一个新的 Stream 中。

List<Integer> list = Arrays.asList(1,2,3,4,5); long countBigThan3 = list.stream() .filter(value -> value > 3) .count();

flatMap 方法

flatMap 可以用于把多个 Stream 连接成一个 Stream。

List<Integer> list = Stream.of(Arrays.asList(1),Arrays.asList(2)) .flatMap(stream -> stream.stream()) .collect(Collectors.toList());

max 和 min 方法

max 和 min 方法用于返回 Stream 中的最大值和最小值。这两个方法接受一个 Comparator 对象作为参数,返回一个 Optional 对象。Comparator 接口新增了一个静态的方法 comparing 来方便构建 Comparator 对象,从而可以使用 lambda 表达式来定义最大值和最小值的比较规则。

List<Integer> list = Arrays.asList(1,2,3,4,5);
int min = list.stream() .min(Comparator.comparing(value -> value)) .get(); int max = list.stream() .max(Comparator.comparing(value -> value)) .get();

本文来源:程序之心,转载请注明出处!

君子曰:学不可以已。
《知识图谱:方法、实践与应用》

知识图谱是较为典型的多学科交叉领域,涉及知识工程、自然语言处理、机器学习、图数据库等多个领域。《知识图谱:方法、实践与应用》系统地介绍知识图谱涉及的关键技术,如知识建模、关系抽取、图存储、自动推理、图谱表示学习、语义搜索、知识问答、图挖掘分析等。此外,本书还尝试将学术前沿和实战结合。

发表感想

© 2016 - 2024 chengxuzhixin.com All Rights Reserved.

浙ICP备2021034854号-1    浙公网安备 33011002016107号