Java 8 引入了 Stream
API,这是一个处理集合数据的强大工具,它允许你以声明式的方式对数据进行各种操作,如过滤、映射、排序、归约等。Stream
不存储数据,而是像管道一样传输和转换数据元素。你可以将 Stream
看作是高级迭代器,它提供了一种更抽象的方式来遍历和操作数据集。
Stream 的主要特点
- 管道化(Pipeline):
Stream
支持一系列中间操作(如filter
,map
,sorted
)和终端操作(如forEach
,collect
,reduce
)。中间操作返回一个新的流,而终端操作会触发实际的计算,并产生结果。 - 惰性求值(Lazy Evaluation):只有当执行到终端操作时,才会真正开始处理数据;在此之前,所有的中间操作都只是记录下来要做什么。
- 并行支持(Parallel Support):
Stream
可以很容易地转换为并行流来进行多线程处理,从而可能提高性能,尤其是在处理大量数据时。
创建 Stream
可以从多种来源创建 Stream
:
- 集合(Collection):
List<T>
,Set<T>
等可以直接通过.stream()
或.parallelStream()
方法得到对应的流。 - 数组(Array): 使用
Arrays.stream(array)
或Stream.of(elements...)
。 - 文件(File):
Files.lines(path)
返回一个包含文件各行文本的流。 - 自定义生成器(Generator):
Stream.generate(Supplier<T>)
和Stream.iterate(T seed, UnaryOperator<T>)
可用于无限流。
常用的操作
中间操作
filter(Predicate<T> predicate)
:根据给定的条件筛选流中的元素。map(Function<T, R> mapper)
:将每个元素转换成另一种形式。flatMap(Function<T, Stream<R>> mapper)
:先映射每个元素为一个新的流,然后把这些流合并成一个流。distinct()
:去除重复元素。sorted([Comparator<? super T> comparator])
:按自然顺序或指定比较器排序。peek(Consumer<? super T> action)
:主要用于调试,可以查看流中元素而不改变它们。
终端操作
forEach(Consumer<? super T> action)
:对每个元素执行给定的动作。collect(Collector<? super T, A, R> collector)
:将流的结果收集到某种容器中,比如列表、集合或自定义对象。reduce(BinaryOperator<T> accumulator)
:累积流中的元素,常用于求和、乘积等聚合运算。count()
:返回流中元素的数量。anyMatch(Predicate<? super T> predicate)
,allMatch(Predicate<? super T> predicate)
,noneMatch(Predicate<? super T> predicate)
:检查是否满足某些条件。findFirst()
,findAny()
:找到第一个或任意一个匹配的元素。
示例代码
下面是一些使用 Stream
API 的简单例子:
java
深色版本
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;public class StreamExample {public static void main(String[] args) {List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");// 打印所有名字的大写形式names.stream().map(String::toUpperCase).forEach(System.out::println);// 过滤出长度大于3的名字,并收集到新的列表中List<String> filteredNames = names.stream().filter(name -> name.length() > 3).collect(Collectors.toList());// 将名字按首字母分组Map<Character, List<String>> groupedByNameInitial = names.stream().collect(Collectors.groupingBy(name -> name.charAt(0)));System.out.println(groupedByNameInitial);}
}
这段代码展示了如何使用 Stream
对字符串列表进行转换、过滤和分组。Stream
API 提供了许多有用的方法来简化集合操作,使得代码更加简洁易读。如果你有特定的需求或者想要了解更多信息,请随时提问!