Stream流小记
Stream流小记
本文给出 Java Stream 流的详细介绍,包含常用方法及其示例。
一、Stream 流基础
Stream 是 Java 8 引入的用于处理集合数据的函数式工具,支持惰性求值(中间操作不执行,终端操作触发计算)。
核心操作:
- 中间操作:返回新的 Stream(如 
filter、map、sorted)。 - 终端操作:触发计算并返回结果(如 
collect、forEach、reduce)。 
创建 Stream 的方式:
// 集合转 Stream
List<Integer> list = Arrays.asList(1, 2, 3, 4);
Stream<Integer> stream1 = list.stream();
// 数组转 Stream
int[] arr = {1, 2, 3};
IntStream stream2 = Arrays.stream(arr);
// 直接创建
Stream<String> stream3 = Stream.of("a", "b", "c");
二、常用 Stream 方法
1. filter(Predicate<T>)
功能:过滤元素,保留满足条件的元素。
示例:过滤偶数。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> even = numbers.stream()
    .filter(n -> n % 2 == 0) // 过滤偶数
    .collect(Collectors.toList()); // 终端操作
System.out.println(even); // [2,4]
注意:
filter()方法会保留条件成立(返回true)的元素,过滤掉条件不成立(返回false)的元素。切记!!!
2. map(Function<T, R>)
功能:将元素转换为另一种类型或格式。
示例:将字符串转为大写。
List<String> names = Arrays.asList("apple", "banana", "orange");
List<String> upperCase = names.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
System.out.println(upperCase); // [APPLE, BANANA, ORANGE]
3. flatMap(Function<T, Stream<R>>)
功能:将每个元素转换为 Stream,然后扁平化为一个 Stream。
示例:将二维数组转为一维数组。
List<List<Integer>> nestedList = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4)
);
List<Integer> flatList = nestedList.stream()
    .flatMap(List::stream) // 将每个子列表转为 Stream,合并成一个 Stream
    .collect(Collectors.toList());
System.out.println(flatList); // [1,2,3,4]
4. sorted()
功能:对元素排序。
示例:升序排序字符串。
List<String> fruits = Arrays.asList("banana", "apple", "orange");
List<String> sorted = fruits.stream()
    .sorted() // 默认自然排序(按字母顺序)
    .collect(Collectors.toList());
System.out.println(sorted); // [apple, banana, orange]
5. distinct()
功能:去重(基于 equals() 方法)。
示例:去除重复数字。
List<Integer> duplicates = Arrays.asList(1, 2, 2, 3, 3, 3);
List<Integer> unique = duplicates.stream()
    .distinct()
    .collect(Collectors.toList());
System.out.println(unique); // [1,2,3]
6. peek(Consumer<T>)
功能:用于调试(类似 forEach,但返回 Stream)。
示例:查看过滤后的中间结果。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
List<Integer> result = numbers.stream()
    .filter(n -> n > 2)
    .peek(n -> System.out.println("Filtered: " + n)) // 输出过滤后的元素
    .collect(Collectors.toList());
// 输出:Filtered: 3, Filtered:4
7. limit(n)
功能:限制结果数量。
示例:取前两个元素。
List<String> colors = Arrays.asList("red", "green", "blue", "yellow");
List<String> limited = colors.stream()
    .limit(2)
    .collect(Collectors.toList());
System.out.println(limited); // [red, green]
8. skip(n)
功能:跳过前 n 个元素。
示例:跳过前两个元素。
List<String> colors = Arrays.asList("red", "green", "blue", "yellow");
List<String> skipped = colors.stream()
    .skip(2)
    .collect(Collectors.toList());
System.out.println(skipped); // [blue, yellow]
9. collect(Collector)
功能:将 Stream 结果收集到集合或对象中。
示例:收集到 List 和 Map。
List<String> fruits = Arrays.asList("apple", "banana", "apple");
Map<String, Long> count = fruits.stream()
    .collect(Collectors.groupingBy(
        Function.identity(), 
        Collectors.counting()
    ));
System.out.println(count); // {apple=2, banana=1}
10. reduce(BinaryOperator<T>)
功能:归约操作(如求和、乘积)。
示例:求和。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
int sum = numbers.stream()
    .reduce(0, Integer::sum); // 初始值为 0,使用 sum 累加
System.out.println(sum); // 10
11. count()
功能:统计元素数量。
示例:统计偶数个数。
long evenCount = Arrays.asList(1, 2, 3, 4, 5).stream()
    .filter(n -> n % 2 == 0)
    .count();
System.out.println(evenCount); // 2
12. max(Comparator) 和 min(Comparator)
功能:获取最大/最小值。
示例:找最大值。
Optional<Integer> max = Arrays.asList(1, 5, 3).stream()
    .max(Integer::compareTo); // 或 .max(Comparator.naturalOrder())
System.out.println(max.orElse(0)); // 5
13. anyMatch(Predicate)、allMatch(Predicate)、noneMatch(Predicate)
功能:检查是否至少一个、全部或没有元素满足条件。
示例:检查是否包含偶数。
boolean hasEven = Arrays.asList(1, 3, 5).stream()
    .anyMatch(n -> n % 2 == 0);
System.out.println(hasEven); // false
14. findFirst() 和 findAny()
功能:获取第一个或任意一个元素(并行流时 findAny 更高效)。
示例:获取第一个元素。
Optional<Integer> first = Arrays.asList(4, 2, 3).stream()
    .sorted()
    .findFirst();
System.out.println(first.orElse(0)); // 2
三、Stream 流的特性
- 惰性求值:中间操作不会立即执行,直到终端操作触发。
 - 无状态:每个元素处理独立,不依赖其他元素。
 - 消费性:元素只能遍历一次,之后需重新生成 Stream。
 
另外注意,多个方法可以叠加使用,如下:
import java.util.*;
import java.util.stream.*;
public class StreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        
        // 过滤偶数、平方、求和
        int sum = numbers.stream()
            .filter(n -> n % 2 == 0)
            .map(n -> n * n)
            .reduce(0, Integer::sum);
        System.out.println(sum); // 20 + 36 = 56
    }
}
四、常见错误与注意事项
- Stream 不能重复使用:一旦终端操作执行后,Stream 会关闭。
 - 并行流的不确定性:
parallelStream()的findAny可能返回任意元素。 Optional处理:max、min、findFirst等返回Optional,需处理空值。

                
            
        
浙公网安备 33010602011771号