在Java 8中,Stream API的引入是函数式编程理念在Java中的一次重大飞跃,它极大地提升了集合(Collection)处理的效率与灵活性。Stream API允许你以声明式方式处理数据集合(包括数组、集合等),通过一系列中间操作(Intermediate Operations)和终端操作(Terminal Operations)的组合,可以简洁地表达复杂的数据处理逻辑。本章将带你走进Stream API的世界,从基础概念到高级应用,逐步掌握这一强大的数据处理工具。
1.1 什么是Stream?
Stream API中的“Stream”是一个来自数据源的元素队列并支持聚合操作。和迭代器(Iterator)类似,但Stream API提供了更丰富的操作,如过滤、映射、排序等,且这些操作可以形成流水线式的数据处理。Stream操作分为中间操作和终端操作:
filter()
, map()
, sorted()
等。forEach()
, collect()
, reduce()
等,执行后Stream流水线结束。1.2 Stream的特点
Stream API提供了多种方式来创建Stream,包括但不限于以下几种:
Collection
接口的stream()
或parallelStream()
方法创建。Arrays.stream(T[] array)
静态方法。Stream.of(T... values)
或Stream.builder()
。lines(Path path)
等方法,用于从文件中读取行作为Stream。
List<String> list = Arrays.asList("apple", "banana", "cherry");
Stream<String> stream = list.stream(); // 从集合创建
Stream<Integer> intStream = Stream.of(1, 2, 3, 4, 5); // 使用静态方法创建
中间操作是Stream处理的核心,它们返回一个新的Stream,可以链式调用多个中间操作。
3.1 过滤(Filter)
使用filter(Predicate<? super T> predicate)
方法,根据提供的谓词函数过滤Stream中的元素。
List<String> filteredList = list.stream()
.filter(s -> s.startsWith("b"))
.collect(Collectors.toList()); // 收集结果到List
3.2 映射(Map)
map(Function<? super T, ? extends R> mapper)
方法将Stream中的每个元素应用给定的函数,并返回一个新的Stream,其中包含应用函数之后的结果。
List<Integer> stringLengthList = list.stream()
.map(String::length)
.collect(Collectors.toList()); // 将字符串列表映射为长度列表
3.3 排序(Sorted)
sorted()
和sorted(Comparator<? super T> comparator)
方法可以对Stream中的元素进行排序。默认是自然排序,也可以提供自定义的Comparator。
List<String> sortedList = list.stream()
.sorted()
.collect(Collectors.toList()); // 自然排序
List<String> customSortedList = list.stream()
.sorted((s1, s2) -> s2.compareTo(s1)) // 逆序排序
.collect(Collectors.toList());
终端操作会触发Stream的实际处理,并产生结果或副作用。
4.1 遍历(ForEach)
forEach(Consumer<? super T> action)
方法用于遍历Stream中的每个元素,并对每个元素执行提供的操作。
list.stream()
.forEach(System.out::println); // 打印每个元素
4.2 收集(Collect)
collect(Collectors.toCollection(Supplier<C> collectionSupplier))
或collect(Collectors.toList())
等方法可以将Stream的元素收集到List、Set等集合中。
List<String> collectedList = list.stream()
.filter(s -> s.startsWith("b"))
.collect(Collectors.toList()); // 收集过滤后的元素到List
4.3 匹配(Match)
Stream API还提供了anyMatch()
, allMatch()
, noneMatch()
等匹配操作,用于检查Stream中的元素是否满足某些条件。
boolean hasBanana = list.stream()
.anyMatch(s -> s.equals("banana")); // 检查是否包含"banana"
4.4 归约(Reduce)
reduce(BinaryOperator<T> accumulator)
方法可以对Stream中的元素进行归约操作,如求和、求积等。
Optional<Integer> sum = list.stream()
.map(String::length) // 映射为长度
.reduce(Integer::sum); // 求和
if (sum.isPresent()) {
System.out.println("Total length: " + sum.get());
}
通过调用集合的parallelStream()
方法,可以获取一个并行Stream。并行Stream利用多核处理器,通过多线程处理数据,从而加速处理过程。但需注意,并行Stream并不总是比顺序Stream快,其性能受数据源大小、处理逻辑复杂度、系统资源等多种因素影响。
List<Integer> parallelResult = list.parallelStream()
.map(String::length)
.collect(Collectors.toList()); // 并行处理
Stream API是Java 8引入的一项革命性特性,它使得集合处理变得更加灵活和高效。通过中间操作和终端操作的组合,可以简洁地表达复杂的数据处理逻辑。掌握Stream API,不仅能够提高编码效率,还能使代码更加简洁、易读。希望本章内容能够帮助你入门Stream API,并在实际开发中灵活运用这一强大的工具。