Java 8 引入的 Stream API 是处理集合数据的强大工具,它允许你以声明式方式处理数据集合,支持各种聚合操作和并行处理。以下是 Stream API 的核心知识点及具体代码示例:
1. Stream 概述
Stream 是数据渠道,用于操作数据源(如集合、数组)所生成的元素序列。注意:
- Stream 自己不会存储元素。
- Stream 不会改变源对象,相反,它们会返回一个持有结果的新 Stream。
- Stream 操作是延迟执行的,这意味着它们会等到需要结果时才执行。
2. Stream 的创建
可以通过集合、数组、静态方法等创建 Stream。
import java.util.*;
import java.util.stream.*;public class StreamCreation {public static void main(String[] args) {// 1. 通过 Collection 接口的 stream() 或 parallelStream() 方法List<String> list = Arrays.asList("apple", "banana", "cherry");Stream<String> streamFromList = list.stream(); // 顺序流Stream<String> parallelStream = list.parallelStream(); // 并行流// 2. 通过 Arrays 类的 stream() 方法Integer[] array = {1, 2, 3, 4, 5};Stream<Integer> streamFromArray = Arrays.stream(array);// 3. 通过 Stream 类的静态方法:of()、iterate()、generate()Stream<String> streamOf = Stream.of("a", "b", "c");Stream<Integer> streamIterate = Stream.iterate(0, n -> n + 2).limit(5); // 0, 2, 4, 6, 8Stream<Double> streamGenerate = Stream.generate(Math::random).limit(3);// 4. 创建空 StreamStream<String> emptyStream = Stream.empty();}
}
3. Stream 的中间操作
中间操作会返回一个新的 Stream,多个中间操作可以连接成一个流水线。常用操作:
- 过滤:
filter(Predicate<T>)
- 映射:
map(Function<T, R>)
、flatMap(Function<T, Stream<R>>)
- 排序:
sorted()
、sorted(Comparator<T>)
- 去重:
distinct()
- 截断:
limit(long maxSize)
- 跳过:
skip(long n)
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;public class StreamIntermediateOperations {public static void main(String[] args) {List<String> words = Arrays.asList("hello", "world", "java", "stream");// 过滤长度大于4的单词,并转为大写,最后排序Stream<String> result = words.stream().filter(word -> word.length() > 4) // 过滤长度>4的单词.map(String::toUpperCase) // 转为大写.sorted(); // 自然排序result.forEach(System.out::println); // 输出: HELLO, WORLD, STREAM}
}
4. Stream 的终止操作
终止操作会触发流水线的执行并产生结果。常用操作:
- 遍历:
forEach(Consumer<T>)
- 匹配:
allMatch()
、anyMatch()
、noneMatch()
- 查找:
findFirst()
、findAny()
- 归约:
reduce()
- 收集:
collect()
- 统计:
count()
、max()
、min()
import java.util.*;
import java.util.stream.Collectors;public class StreamTerminalOperations {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 1. 匹配与查找boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0); // falseboolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0); // trueOptional<Integer> firstEven = numbers.stream().filter(n -> n % 2 == 0).findFirst(); // 2// 2. 归约:计算总和int sum = numbers.stream().reduce(0, Integer::sum); // 55// 3. 收集:转为集合或统计List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList()); // [2, 4, 6, 8, 10]// 4. 分组:按奇偶分组Map<Boolean, List<Integer>> groupedByEven = numbers.stream().collect(Collectors.partitioningBy(n -> n % 2 == 0));// 5. 统计IntSummaryStatistics stats = numbers.stream().mapToInt(Integer::intValue).summaryStatistics();System.out.println("Count: " + stats.getCount()); // 10System.out.println("Sum: " + stats.getSum()); // 55System.out.println("Average: " + stats.getAverage()); // 5.5}
}
5. 并行流与串行流
- 串行流:单线程处理流中的元素。
- 并行流:内部使用 Fork/Join 框架多线程并行处理(适合大数据量)。
import java.util.Arrays;
import java.util.List;public class ParallelStreamExample {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);// 串行流(单线程)numbers.stream().map(n -> {System.out.println(Thread.currentThread().getName() + ": " + n);return n * 2;}).forEach(System.out::println);System.out.println("---");// 并行流(多线程)numbers.parallelStream().map(n -> {System.out.println(Thread.currentThread().getName() + ": " + n);return n * 2;}).forEach(System.out::println);}
}
6. Stream 的惰性求值
中间操作不会立即执行,只有遇到终止操作时才会触发执行。
import java.util.Arrays;
import java.util.List;public class StreamLaziness {public static void main(String[] args) {List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");// 中间操作不会执行names.stream().filter(name -> {System.out.println("Filtering: " + name);return name.length() > 4;}).map(name -> {System.out.println("Mapping: " + name);return name.toUpperCase();});// 没有终止操作,不会输出任何内容// 添加终止操作后触发执行names.stream().filter(name -> {System.out.println("Filtering: " + name);return name.length() > 4;}).map(name -> {System.out.println("Mapping: " + name);return name.toUpperCase();}).forEach(System.out::println);}
}
总结
Stream API 的核心流程:创建 Stream → 中间操作(过滤、映射等)→ 终止操作(收集结果)。合理使用 Stream 可以让代码更简洁、更具可读性,同时利用并行流提升大数据处理效率。