# Java 8 Streams的简单介绍与入门

Stream是Java 8引入的新feature,非常值得学习。本文通过简单的例子来介绍stream的基本操作,先来一个整体认识。

# 1 Stream API

在Java 8的新特性中,引入流是非常主要的一个。其中很多API都在类Stream<T>中。

# 1.1 生成Stream

当我们需要生成Stream时,是非常灵活的,可以从ArrayCollection生成,这时会用到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操作,返回了一个流元素个数作为结果。

# 2.1 迭代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开发人员都应该掌握。

上次更新: 2023/8/18 23:39:36