Java 中的 Stream API 常用总结

2023-12-23 06:25:38

Java 8 引入了 Stream API,它提供了一种新的抽象,使得在集合数据上进行函数式编程变得更加简单、高效和可维护。下面我们将探讨 Stream API 的几个常用方法和功能:
创建流

创建流操作

● 从集合创建:

 使用 stream() 方法从集合(如 List、Set、Map)创建 Stream。
List<String> myList = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = myList.stream();

● 从数组创建:

使用 Arrays.stream() 方法从数组创建 Stream。
int[] numbers = {1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(numbers);

中间操作

filter()

● 注意事项:

○ 用于筛选流中的元素,需提供一个 Predicate。
○ 操作结果是一个新的 Stream,其中只包含符合条件的元素。
○ 注意 Predicate 条件的复杂性和可读性。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// 输出筛选后的偶数列表 [2, 4]
System.out.println(evenNumbers);

map()

● 注意事项:

○ 用于将流中的每个元素映射成另一个元素。
○ 映射函数应保持无状态,不修改外部变量。

javaCopy code
List<String> words = Arrays.asList("apple", "banana", "orange");
List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
// 输出单词长度列表 [5, 6, 6]
System.out.println(wordLengths);

当使用 Java Stream API 时,每个方法都有一些注意事项需要考虑。以下是常用 Stream API 方法、相关的注意事项和例子的整合:
filter()

● 注意事项:

○ 用于筛选流中的元素,需提供一个 Predicate。
○ 操作结果是一个新的 Stream,其中只包含符合条件的元素。
○ 注意 Predicate 条件的复杂性和可读性。

javaCopy code
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
                                   .filter(n -> n % 2 == 0)
                                   .collect(Collectors.toList());
// 输出筛选后的偶数列表 [2, 4]
System.out.println(evenNumbers);
map()
● 注意事项:

○ 用于将流中的每个元素映射成另一个元素。
○ 映射函数应保持无状态,不修改外部变量。

javaCopy code
List<String> words = Arrays.asList("apple", "banana", "orange");
List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(Collectors.toList());
// 输出单词长度列表 [5, 6, 6]
System.out.println(wordLengths);
distinct()
● 注意事项:

○ 用于去除流中的重复元素,基于 equals() 方法进行判断。
○ 要确保正确实现了对象的 equals() 方法。

javaCopy code
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> uniqueNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
// 输出去重后的数字列表 [1, 2, 3, 4, 5]
System.out.println(uniqueNumbers);
sorted()
● 注意事项:

○ 用于对流中的元素进行排序,可自然排序或自定义排序。
○ 自定义排序需保证正确性和稳定性。

javaCopy code
List<String> words = Arrays.asList("apple", "banana", "orange");
List<String> sortedWords = words.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
// 输出倒序排序后的单词列表 [orange, banana, apple]
System.out.println(sortedWords);
终端操作:
forEach()
● 注意事项:

○ 对流中的每个元素执行指定操作,适合简单的遍历操作。
○ 不保证元素的处理顺序。

List<String> fruits = Arrays.asList("apple", "banana", "orange");
fruits.stream()
.forEach(System.out::println);
// 输出所有水果名称(无序输出)
// apple
// banana
// orange

collect()

注意事项:

● 用于将流中的元素收集到集合或其他数据结构中。

Collectors.toList()

● 用途:
○ toList() 方法将流中的元素收集到一个 List 中。

List<String> words = Arrays.asList("Java", "Stream", "API");
List<String> collectedList = words.stream()
.collect(Collectors.toList());
// 将流中的元素收集到 List 中
System.out.println(collectedList); // 输出:[Java, Stream, API]

Collectors.toSet()

● 用途:
○ toSet() 方法将流中的元素收集到一个 Set 中。

javaCopy code
List<String> words = Arrays.asList("Java", "Stream", "API");
Set<String> collectedSet = words.stream()
.collect(Collectors.toSet());
// 将流中的元素收集到 Set 中
System.out.println(collectedSet); // 输出:[Java, Stream, API](无序)

Collectors.toMap()

● 用途:
○ toMap() 方法将流中的元素按照键值对的方式收集到一个 Map 中。

javaCopy code
List<String> words = Arrays.asList("Java", "Stream", "API");
Map<Integer, String> collectedMap = words.stream()
.collect(Collectors.toMap(String::length, s -> s));
// 将流中的元素按照长度作为键收集到 Map 中
System.out.println(collectedMap); // 输出:{4=Java, 6=Stream, 3=API}


注意: 这种时候一定要进行去重操作,不然会报错,这里如果出现了重复就保留之前的
allUserList.stream()
                .collect(Collectors.toMap( CompanyUserListDO::getName,
                        CompanyUserListDO::getCloudUserId,
                        (existing, replacement) -> existing))

Collectors.joining()

● 用途:
○ joining() 方法将流中的元素连接成一个字符串。

javaCopy code
List<String> words = Arrays.asList("Java", "Stream", "API");
String concatenated = words.stream()
.collect(Collectors.joining(", "));
// 将流中的元素用逗号连接成字符串
System.out.println(concatenated); // 输出:Java, Stream, API

Collectors.groupingBy()

● 用途:
○ groupingBy() 方法按照某个分类器对流中的元素进行分组,生成一个 Map。

javaCopy code
List<String> words = Arrays.asList("Java", "Stream", "API");
Map<Integer, List<String>> groupedByLength = words.stream()
.collect(Collectors.groupingBy(String::length));
// 按照字符串长度对流中的元素进行分组
System.out.println(groupedByLength); // 输出:{3=[Java], 5=[Stream], 3=[API]}

Collectors.partitioningBy()

● 用途:
○ partitioningBy() 方法根据某个条件对流中的元素进行分区,生成一个 Map。

javaCopy code
List<String> words = Arrays.asList("Java", "Stream", "API");
Map<Boolean, List<String>> partitionedByLength = words.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 4));
// 根据字符串长度是否大于4对流中的元素进行分区
System.out.println(partitionedByLength); // 输出:{false=[Java, API], true=[S

● 需要考虑线程安全性和并发性。

count()

注意事项:

● 用于获取流中元素的数量,返回值为 long 类型。
● 终端操作前不会开始计算。

javaCopy code
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream()
.filter(n -> n > 2)
.count();
// 输出大于2的数字个数
System.out.println(count); // 输出:3

并行流

● 使用 parallelStream():将 Stream 转换为并行流,实现并行处理,提高处理速度。

javaCopy code
List<String> words = Arrays.asList("apple", "banana", "orange");
long count = words.parallelStream()
.filter(w -> w.length() > 5)
.count();
System.out.println(count); // 输出符合条件的元素个数

Stream 的优势

● 简化代码:Stream API 提供了一种更简洁的方式来处理集合数据,减少了冗长的迭代和操作代码。
● 更高的性能:利用并行流进行并行处理,可以充分利用多核处理器,提高程序性能。
结语
Java Stream API 提供了丰富的功能和便利的方法,用于处理集合数据,让数据操作更加灵活高效。通过使用 Stream API,可以以更简洁和直观的方式处理集合数据,从而提高编程效率和代码质量。

文章来源:https://blog.csdn.net/Nanki_/article/details/135163203
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。