关于 Java Stream 流的常见操作及示例,涵盖数据过滤、转换、聚合等高频使用场景

一、基础操作

  1. 过滤数据 (filter)
    List numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
    List evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0) // 过滤偶数
    .collect(Collectors.toList()); // [2, 4, 6]
  2. 数据转换 (map)
    List names = Arrays.asList("Alice", "Bob", "Charlie");
    List nameLengths = names.stream()
    .map(String::length) // 转换为名字长度
    .collect(Collectors.toList()); // [5, 3, 7]
  3. 扁平化嵌套集合 (flatMap)
    List<List> nestedList = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4, 5)
    );
    List flatList = nestedList.stream()
    .flatMap(Collection::stream) // 扁平化为单一流
    .collect(Collectors.toList()); // [1, 2, 3, 4, 5]

二、聚合操作

  1. 去重 (distinct)
    List nums = Arrays.asList(1, 2, 2, 3, 3, 3);
    List uniqueNums = nums.stream()
    .distinct() // 去重
    .collect(Collectors.toList()); // [1, 2, 3]
  2. 排序 (sorted)
    List words = Arrays.asList("banana", "apple", "cherry");
    List sortedWords = words.stream()
    .sorted() // 自然排序
    .collect(Collectors.toList()); // [apple, banana, cherry]

// 自定义排序规则
List customSorted = words.stream()
.sorted((a, b) -> b.length() - a.length()) // 按长度倒序
.collect(Collectors.toList()); // [banana, cherry, apple]
3. 限制与跳过 (limit/skip)
List nums = IntStream.range(1, 10) // 1~9
.skip(3) // 跳过前3个 → 4,5,6,7,8,9
.limit(4) // 取前4个 → 4,5,6,7
.boxed()
.collect(Collectors.toList());

三、终端操作

  1. 统计聚合
    List numbers = Arrays.asList(1, 2, 3, 4, 5);

// 求和
int sum = numbers.stream().mapToInt(Integer::intValue).sum(); // 15

// 平均值
OptionalDouble avg = numbers.stream().mapToInt(Integer::intValue).average();

// 最大值/最小值
Optional max = numbers.stream().max(Integer::compareTo);
2. 匹配检查
List nums = Arrays.asList(2, 4, 6, 8);
boolean allEven = nums.stream().allMatch(n -> n % 2 == 0); // true
boolean anyGreaterThan5 = nums.stream().anyMatch(n -> n > 5); // true
boolean noneNegative = nums.stream().noneMatch(n -> n < 0); // true

  1. 遍历元素 (forEach)
    List list = Arrays.asList("a", "b", "c");
    list.stream().forEach(System.out::println); // 输出 a b c

四、高级操作

  1. 分组 (groupingBy)
    List words = Arrays.asList("apple", "banana", "cherry", "date");
    Map<Integer, List> groupByLength = words.stream()
    .collect(Collectors.groupingBy(String::length));
    // 结果:

  2. 分区 (partitioningBy)
    List numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
    Map<Boolean, List> partitioned = numbers.stream()
    .collect(Collectors.partitioningBy(n -> n % 2 == 0));
    // 结果:

  3. 连接字符串 (joining)
    List languages = Arrays.asList("Java", "Python", "C++");
    String joined = languages.stream()
    .collect(Collectors.joining(", ", "[", "]")); // [Java, Python, C++]

  4. 归约操作 (reduce)
    List nums = Arrays.asList(1, 2, 3, 4);
    Optional product = nums.stream()
    .reduce((a, b) -> a * b); // 123*4=24

五、并行流
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 并行计算总和
int sum = numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();

// 注意线程安全问题
List safeList = Collections.synchronizedList(new ArrayList<>());
numbers.parallelStream().forEach(safeList::add);

六、实用技巧

  1. 集合转 Map
    List people = Arrays.asList(
    new Person("Alice", 25),
    new Person("Bob", 30)
    );

Map<String, Integer> nameToAge = people.stream()
.collect(Collectors.toMap(Person::getName, Person::getAge));

  1. 跳过空值
    List list = Arrays.asList("a", null, "c", null);
    List nonNullList = list.stream()
    .filter(Objects::nonNull)
    .collect(Collectors.toList()); // [a, c]

  2. 处理文件流
    try (Stream lines = Files.lines(Paths.get("data.txt"))) {
    List filteredLines = lines
    .filter(line -> line.contains("error"))
    .collect(Collectors.toList());
    } // 自动关闭流

注意事项
流只能消费一次:流被终端操作消费后不可重复使用。

避免副作用:不要在 forEach 中修改外部变量(推荐使用不可变对象)。

性能权衡:小数据集优先用顺序流,大数据集考虑并行流。

资源管理:使用 try-with-resources 管理需要关闭的流(如 Files.lines)。

掌握这些操作可显著提升集合处理的简洁性和效率!

posted @ 2025-02-25 17:53  oceanW  阅读(132)  评论(0)    收藏  举报