Stream是Java 8引入的新feature,非常值得学习。本文通过简单的例子来介绍stream的基本操作,先来一个整体认识。
1 Stream API
在Java 8的新特性中,引入流是非常主要的一个。其中很多API都在类Stream<T>
中。
1.1 生成Stream
当我们需要生成Stream
时,是非常灵活的,可以从Array
或Collection
生成,这时会用到stream()
和of()
方法,如下:
String[] arr = new String[]{"a", "b", "c"};
Stream<String> stream = Arrays.stream(arr);
stream = Stream.of("a", "b", "c");
在Java 8中,每个Collection接口的实现都已经添加了stream()
作为default method,以提供直接从Collection转化为Stream。
例如:
List<String> list = asList("a", "b", "c", "c");
stream = list.stream();
1.2 多线程的Stream
Stream API提供了parallelStream()
方法,来实现流式元素的并行操作,如:
list.parallelStream().forEach(System.out::println);
2 Stream操作
得益于JDK提供的许多非常有用的流操作,使得我们的代码可以更简洁美观,逻辑更清晰。
而Stream操作又分为两种,一种为intermediate操作(返回流),另一种为terminal操作(返回特定的结果)。
需要特别注意的是两者的区别是很大的。Intermediate操作支持链式模式,而且不会改变源,这一点非常重要。
例如:
long count = list.stream().distinct().count();
上面的distinct()
方法是一种intermediate操作,会返回一个新的流;而count()
方法是一个terminal操作,返回了一个流元素个数作为结果。
21. 迭代iterating
迭代应该是程序极其常见的一种操作,平常我们可能会这样写:
for (String str : list) {
System.out.println(str);
}
而使用流,操作则变成了这样:
list.stream().forEach(System.out::println);
2.2 过滤filtering
过滤就是只选择满足条件的元素,如:
list = asList("aa", "bb", "cc", "abc");
Stream<String> result = list.stream().filter(str -> str.contains("a"));
2.3 映射mapping
映射可以理解为转化,就带着元素A的流StreamA,转化为带元素B的流StreamB。还是看例子最直观:
list = asList("123", "322", "3221", "34241");
Stream<Integer> integerStream = list.stream()
.map(str -> Integer.parseInt(str));
Note:还有一个类似的方法为flatMap(),这个后续再讨论,有兴趣的可以自己研究。
2.4 匹配matching
匹配用于判断流是否满足某些条件,如下:
boolean isAnyMatch = list.stream().anyMatch(str -> str.contains("d"));
boolean isAllMatch = list.stream().allMatch(str -> str.contains("d"));
boolean isNoneMatch = list.stream().noneMatch(str -> str.contains("d"));
匹配与过滤有一点像,都用到了条件判断predicate
。
匹配是terminal操作,返回一个boolean
结果;
过滤是intermediate操作,返回一个流。
2.5 规约Reduction
List<Integer> integers = asList(1, 2, 3, 4, 5);
Integer reduced = integers.stream().reduce(2, (a, b) -> a + b);
2.6 聚合Collecting
聚合是非常有用的操作,特别是当我们需要将一个Stream转化为Collection或Map的时候。工具类Collectors
提供了几乎所有的collecting操作,下面例子用于将Stream转化为List。
list = asList("aa", "bb", "cc", "abc");
List<String> results = list.stream()
.filter(str->str.contains("a"))
.collect(Collectors.toList());
3 总结
Stream真的是非常有用,而且非常方便,Java开发人员都应该掌握。