Java Stream API详解
Java Stream API详解
什么是Stream
Stream是Java 8引入的用于处理集合数据的API,支持声明式、函数式的编程风格。
创建Stream
public class StreamCreation {
public static void main(String[] args) {
// 1. 从集合创建
List<String> list = List.of("a", "b", "c");
Stream<String> stream1 = list.stream();
Stream<String> parallelStream1 = list.parallelStream();
// 2. 从数组创建
int[] arr = {1, 2, 3, 4, 5};
IntStream stream2 = Arrays.stream(arr);
// 3. 直接创建
Stream<String> stream3 = Stream.of("x", "y", "z");
Stream<Integer> stream4 = Stream.of(1, 2, 3);
// 4. 生成无限流
Stream<Double> randoms = Stream.generate(Math::random).limit(5);
Stream<Integer> naturals = Stream.iterate(1, n -> n + 1).limit(10);
// 5. 从文件创建
Stream<String> lines = Files.lines(Path.of("data.txt"));
}
}
中间操作
public class StreamTransform {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie", "David", "Eve");
// filter:过滤
List<String> longNames = names.stream()
.filter(name -> name.length() > 3)
.toList();
// [Alice, Charlie, David]
// map:转换
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.toList();
// [ALICE, BOB, CHARLIE, DAVID, EVE]
// flatMap:扁平化映射
List<List<Integer>> nested = List.of(
List.of(1, 2), List.of(3, 4), List.of(5, 6)
);
List<Integer> flat = nested.stream()
.flatMap(Collection::stream)
.toList();
// [1, 2, 3, 4, 5, 6]
// distinct:去重
List<Integer> numbers = List.of(1, 2, 2, 3, 3, 4);
List<Integer> unique = numbers.stream()
.distinct()
.toList();
// [1, 2, 3, 4]
// sorted:排序
List<String> sorted = names.stream()
.sorted()
.toList();
// peek:调试查看
List<String> result = names.stream()
.filter(name -> name.length() > 3)
.peek(name -> System.out.println("过滤后: " + name))
.map(String::toLowerCase)
.toList();
// limit & skip:分页
List<String> page = names.stream()
.skip(2)
.limit(2)
.toList();
// [Charlie, David]
}
}
终端操作
public class StreamTerminal {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// collect:收集结果
List<Integer> evens = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
// toList
List<String> names = List.of("Alice", "Bob", "Charlie");
List<String> upper = names.stream()
.map(String::toUpperCase)
.toList();
// joining
String joined = names.stream()
.collect(Collectors.joining(", "));
// "Alice, Bob, Charlie"
// groupingBy
List<String> words = List.of("apple", "banana", "cherry", "avocado");
Map<Character, List<String>> grouped = words.stream()
.collect(Collectors.groupingBy(w -> w.charAt(0)));
// {a=[apple, avocado], b=[banana], c=[cherry]}
// counting
long count = numbers.stream()
.filter(n -> n > 5)
.count();
// summing
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();
// reduce
int product = numbers.stream()
.reduce(1, (a, b) -> a * b);
Optional<Integer> max = numbers.stream()
.max(Integer::compareTo);
Optional<Integer> min = numbers.stream()
.min(Integer::compareTo);
// forEach
numbers.stream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
// toArray
Integer[] array = numbers.stream()
.toArray(Integer[]::new);
}
}
Collectors高级用法
public class CollectorsAdvanced {
public static void main(String[] args) {
List<Employee> employees = List.of(
new Employee("张三", "技术部", 8000),
new Employee("李四", "技术部", 12000),
new Employee("王五", "市场部", 9000),
new Employee("赵六", "市场部", 11000)
);
// 分组统计
Map<String, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// 分组计数
Map<String, Long> deptCount = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.counting()
));
// 分组求和
Map<String, Integer> deptSalary = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)
));
// 分区
Map<Boolean, List<Employee>> partitioned = employees.stream()
.collect(Collectors.partitioningBy(e -> e.getSalary() > 10000));
// 统计信息
IntSummaryStatistics stats = employees.stream()
.mapToInt(Employee::getSalary)
.summaryStatistics();
System.out.println("平均: " + stats.getAverage());
System.out.println("最大: " + stats.getMax());
System.out.println("最小: " + stats.getMin());
}
}
并行流
public class ParallelStreamDemo {
public static void main(String[] args) {
List<Integer> numbers = IntStream.rangeClosed(1, 1000000).boxed().toList();
// 串行流
long start = System.nanoTime();
long count = numbers.stream()
.filter(n -> isPrime(n))
.count();
System.out.println("串行: " + (System.nanoTime() - start) / 1000000 + "ms");
// 并行流
start = System.nanoTime();
count = numbers.parallelStream()
.filter(n -> isPrime(n))
.count();
System.out.println("并行: " + (System.nanoTime() - start) / 1000000 + "ms");
}
private static boolean isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}
}
方法引用
public class MethodReferenceDemo {
public static void main(String[] args) {
List<String> names = List.of("Alice", "Bob", "Charlie");
// 静态方法引用
names.stream()
.map(String::toUpperCase)
.toList();
// 实例方法引用
names.stream()
.map(String::length)
.toList();
// 构造器引用
List<String> strings = List.of("1", "2", "3");
List<Integer> integers = strings.stream()
.map(Integer::new)
.toList();
}
}
总结
Stream API让集合操作更简洁、更函数式。掌握filter、map、reduce等核心操作,能大幅提升代码可读性和开发效率。