Java 8引入了Stream
API,这是对集合操作的一次重大革新。Stream
API提供了一种高效且易于使用的方式来处理集合数据。通过Stream
,开发者可以以声明式的方式处理数据,而不必关心底层的实现细节。本文将详细介绍Stream
的使用方法,包括如何创建Stream
、中间操作、终端操作、并行流以及性能考虑等。
Stream
是Java 8中引入的一个新概念,它代表一个元素序列,支持顺序和并行处理。Stream
本身并不存储数据,而是从数据源(如集合、数组、I/O通道等)获取数据,并对其进行一系列操作。Stream
的操作分为中间操作和终端操作。中间操作返回一个新的Stream
,而终端操作则产生一个结果或副作用。
在Java 8中,可以通过多种方式创建Stream
。以下是几种常见的创建方式:
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
Stream.of
创建Stream<String> stream = Stream.of("a", "b", "c");
Stream.iterate
创建Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(10);
Stream.generate
创建Stream<Double> stream = Stream.generate(Math::random).limit(5);
Stream<String> lines = Files.lines(Paths.get("file.txt"));
中间操作是对Stream
中的元素进行处理的操作,返回一个新的Stream
。常见的中间操作包括filter
、map
、flatMap
、distinct
、sorted
、peek
、limit
和skip
。
filter
操作用于过滤Stream
中的元素,只保留满足条件的元素。
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> filteredStream = list.stream().filter(s -> s.startsWith("a"));
map
操作用于将Stream
中的每个元素映射为另一个元素。
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> mappedStream = list.stream().map(String::toUpperCase);
flatMap
操作用于将Stream
中的每个元素映射为一个Stream
,然后将这些Stream
合并为一个Stream
。
List<List<String>> list = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
Stream<String> flatMappedStream = list.stream().flatMap(Collection::stream);
distinct
操作用于去除Stream
中的重复元素。
List<String> list = Arrays.asList("a", "b", "a", "c");
Stream<String> distinctStream = list.stream().distinct();
sorted
操作用于对Stream
中的元素进行排序。
List<String> list = Arrays.asList("c", "a", "b");
Stream<String> sortedStream = list.stream().sorted();
peek
操作用于对Stream
中的每个元素执行一个操作,通常用于调试。
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> peekedStream = list.stream().peek(System.out::println);
limit
操作用于截取Stream
中的前N个元素。
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> limitedStream = list.stream().limit(2);
skip
操用于跳过Stream
中的前N个元素。
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> skippedStream = list.stream().skip(2);
终端操作是对Stream
中的元素进行最终处理的操作,产生一个结果或副作用。常见的终端操作包括forEach
、toArray
、reduce
、collect
、min
、max
、count
、anyMatch
、allMatch
、noneMatch
、findFirst
和findAny
。
forEach
操作用于对Stream
中的每个元素执行一个操作。
List<String> list = Arrays.asList("a", "b", "c");
list.stream().forEach(System.out::println);
toArray
操作用于将Stream
中的元素转换为数组。
List<String> list = Arrays.asList("a", "b", "c");
String[] array = list.stream().toArray(String[]::new);
reduce
操作用于将Stream
中的元素通过某种方式组合起来,产生一个结果。
List<Integer> list = Arrays.asList(1, 2, 3, 4);
Optional<Integer> sum = list.stream().reduce(Integer::sum);
collect
操作用于将Stream
中的元素收集到一个集合中。
List<String> list = Arrays.asList("a", "b", "c");
List<String> collectedList = list.stream().collect(Collectors.toList());
min
操作用于找出Stream
中的最小元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4);
Optional<Integer> min = list.stream().min(Integer::compareTo);
max
操作用于找出Stream
中的最大元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4);
Optional<Integer> max = list.stream().max(Integer::compareTo);
count
操作用于统计Stream
中的元素个数。
List<String> list = Arrays.asList("a", "b", "c");
long count = list.stream().count();
anyMatch
操作用于判断Stream
中是否有元素满足某个条件。
List<String> list = Arrays.asList("a", "b", "c");
boolean anyMatch = list.stream().anyMatch(s -> s.startsWith("a"));
allMatch
操作用于判断Stream
中的所有元素是否都满足某个条件。
List<String> list = Arrays.asList("a", "b", "c");
boolean allMatch = list.stream().allMatch(s -> s.startsWith("a"));
noneMatch
操作用于判断Stream
中是否没有元素满足某个条件。
List<String> list = Arrays.asList("a", "b", "c");
boolean noneMatch = list.stream().noneMatch(s -> s.startsWith("d"));
findFirst
操作用于找出Stream
中的第一个元素。
List<String> list = Arrays.asList("a", "b", "c");
Optional<String> first = list.stream().findFirst();
findAny
操作用于找出Stream
中的任意一个元素。
List<String> list = Arrays.asList("a", "b", "c");
Optional<String> any = list.stream().findAny();
Stream
API支持并行处理,可以通过parallelStream
方法将Stream
转换为并行流。并行流会将任务分解为多个子任务,并行执行,从而提高处理效率。
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> parallelStream = list.parallelStream();
需要注意的是,并行流并不总是比顺序流更快,特别是在数据量较小或任务本身较为简单的情况下。因此,在使用并行流时,需要根据具体情况进行权衡。
虽然Stream
API提供了强大的功能,但在使用时也需要注意性能问题。以下是一些性能优化的建议:
Stream
,因此应尽量减少中间操作的数量。Stream
中使用阻塞操作:阻塞操作会降低Stream
的性能,应尽量避免。Stream
时注意内存消耗:Stream
操作可能会消耗大量内存,特别是在处理大数据集时,应注意内存的使用情况。Stream
API在实际开发中有许多常见的用例,以下是一些典型的例子:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> result = names.stream()
.filter(name -> name.length() > 4)
.map(String::toUpperCase)
.collect(Collectors.toList());
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Map<Integer, Long> result = names.stream()
.collect(Collectors.groupingBy(String::length, Collectors.counting()));
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Alice");
List<String> result = names.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> result = names.parallelStream()
.map(String::toUpperCase)
.collect(Collectors.toList());
Java 8中的Stream
API为集合操作提供了一种高效且易于使用的方式。通过Stream
,开发者可以以声明式的方式处理数据,而不必关心底层的实现细节。本文详细介绍了Stream
的创建、中间操作、终端操作、并行流以及性能考虑等内容,并提供了常见的用例。希望本文能帮助读者更好地理解和使用Stream
API。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。