
Stream 是 JDK 8 中处理集合(Collection)数据的新抽象,它可以让你以声明式的方式处理数据,类似于使用 SQL 语句进行数据库查询。
List names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 传统方式
List<String> result = new ArrayList<>();
for (String name : names) {
if (name.startsWith("A")) {
result.add(name.toUpperCase());
}
}
// Stream 方式 List<String> streamResult = names.stream() .filter(name -> name.startsWith("A")) .map(String::toUpperCase) .collect(Collectors.toList());
#后端 #每天一个知识点| 操作类型 | 方法示例 | 返回值 | 特点 | | ---
| 中间操作 | filter(), map(), sorted() | Stream | 惰性执行,可链式调用 | | 终止操作 | forEach(), collect(), count() | 非 Stream | 立即执行,关闭流 |
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
Stream<String> stream = Stream.of("a", "b", "c");
IntStream intStream = IntStream.range(1, 5); // 1,2,3,4
IntStream closedStream = IntStream.rangeClosed(1, 5); // 1,2,3,4,5
// 生成10个随机数
Stream<Double> randomStream = Stream.generate(Math::random).limit(10);
// 创建斐波那契数列 Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]}) .limit(10) .map(t -> t[0]) .forEach(System.out::println);
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> result = names.stream()
.filter(name -> name.length() > 3)
.collect(Collectors.toList());
// 结果: [Alice, Charlie, David]
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
// 结果: [5, 3, 7]
List<List<String>> listOfLists = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
List<String> flatList = listOfLists.stream() .flatMap(List::stream) .collect(Collectors.toList()); // 结果: [a, b, c, d]
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
List<Integer> distinctNumbers = numbers.stream()
.distinct()
.collect(Collectors.toList());
// 结果: [1, 2, 3]
List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
List<String> sortedNames = names.stream()
.sorted()
.collect(Collectors.toList());
// 结果: [Alice, Bob, Charlie]
// 自定义排序 List<String> customSorted = names.stream() .sorted((a, b) -> b.length() - a.length()) .collect(Collectors.toList()); // 结果: [Charlie, Alice, Bob]
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> limited = numbers.stream() .limit(5) .collect(Collectors.toList()); // 结果: [1, 2, 3, 4, 5]
List<Integer> skipped = numbers.stream() .skip(5) .collect(Collectors.toList()); // 结果: [6, 7, 8, 9, 10]
List<String> result = Stream.of("one", "two", "three")
.filter(s -> s.length() > 3)
.peek(s -> System.out.println("Filtered value: " + s))
.map(String::toUpperCase)
.peek(s -> System.out.println("Mapped value: " + s))
.collect(Collectors.toList());
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
// 转换为List
List<String> list = stream.collect(Collectors.toList());
// 转换为 Set Set<String> set = stream.collect(Collectors.toSet());
// 转换为 Map Map<String, Integer> map = stream.collect( Collectors.toMap(s -> s, String::length) );
// 连接字符串 String joined = stream.collect(Collectors.joining(", "));
// 分组 Map<Integer, List<String>> grouped = names.stream() .collect(Collectors.groupingBy(String::length));
// 分区 Map<Boolean, List<String>> partitioned = names.stream() .collect(Collectors.partitioningBy(s -> s.length() > 3));
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 求和 Optional<Integer> sum = numbers.stream().reduce(Integer::sum); // 或 Integer sum2 = numbers.stream().reduce(0, Integer::sum);
// 求最大值 Optional<Integer> max = numbers.stream().reduce(Integer::max);
// 字符串连接 Optional<String> concat = Stream.of("a", "b", "c").reduce(String::concat);
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0); // false boolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0); // true boolean noneEven = numbers.stream().noneMatch(n -> n % 2 == 0); // false
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Optional<String> first = names.stream().findFirst(); Optional<String> any = names.stream().findAny();
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream().count(); IntSummaryStatistics stats = numbers.stream() .mapToInt(Integer::intValue) .summaryStatistics();
System.out.println("最大值: " +
System.out.println("最小值: " +
System.out.println("总和: " +
System.out.println("平均值: " + stats.getAverage());
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 方法1:从集合创建 Stream<String> parallelStream = names.parallelStream();
// 方法2:将顺序流转为并行流 Stream<String> parallel = names.stream().parallel();
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
long startTime = System.currentTimeMillis(); long sum = numbers.parallelStream() .mapToLong(Integer::longValue) .sum(); long endTime = System.currentTimeMillis();
System.out.println("总和: " +
System.out.println("执行时间: " + (endTime - startTime) + "ms");
class Employee {
private String name;
private String department;
private double salary;
private int age;
// 构造方法、getter、setter省略
}
List<Employee> employees = Arrays.asList( new Employee("Alice", "IT", 5000, 25), new Employee("Bob", "HR", 4000, 30), new Employee("Charlie", "IT", 6000, 35), new Employee("David", "Finance", 5500, 28) );
// 1.
Map<String, Double> avgSalaryByDept = employees.stream() .collect(Collectors.groupingBy( Employee::getDepartment, Collectors.averagingDouble(Employee::getSalary) ));
// 2.
Optional<Employee> highestPaidInIT = employees.stream() .filter(e -> "IT".equals(e.getDepartment())) .max(Comparator.comparingDouble(Employee::getSalary));
// 3.
List<Employee> top3ByAge = employees.stream() .sorted(Comparator.comparingInt(Employee::getAge).reversed()) .limit(3) .collect(Collectors.toList());
// 4.
Map<String, Long> employeeCountByDept = employees.stream() .collect(Collectors.groupingBy( Employee::getDepartment, Collectors.counting() ));
// 读取文件并统计单词频率
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
Map<String, Long> wordCount = lines
.flatMap(line -> Arrays.stream(line.split("s+")))
.map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase())
.filter(word -> !word.isEmpty())
.collect(Collectors.groupingBy(
word -> word,
Collectors.counting()
));
// 按频率排序
wordCount.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.limit(10)
.forEach(entry ->
System.out.println(entry.getKey() + ": " + entry.getValue()) ); } catch (IOException e) { e.printStackTrace(); }
// 多层数据转换和聚合
class Order {
private String customer;
private List<OrderItem> items;
private LocalDate orderDate;
// 构造方法、getter、setter省略
}
class OrderItem { private String product; private int quantity; private double price; // 构造方法、getter、setter 省略 }
List<Order> orders = // 初始化订单数据
// 计算每个客户的总消费金额 Map<String, Double> customerTotal = orders.stream() .collect(Collectors.groupingBy( Order::getCustomer, Collectors.summingDouble(order ->
order.getItems().stream() .mapToDouble(item -> item.getQuantity() * item.getPrice()) .sum() ) ));
// 找出最畅销的产品 Optional<String> bestSellingProduct = orders.stream() .flatMap(order -> order.getItems().stream()) .collect(Collectors.groupingBy( OrderItem::getProduct, Collectors.summingInt(OrderItem::getQuantity) )) .entrySet().stream() .max(Map.Entry.comparingByValue()) .map(Map.Entry::getKey);
JDK 8 的 Stream API 为集合操作提供了强劲的函数式编程能力,通过链式调用和惰性求值等特性,可以写出更简洁、易读、高效的代码。掌握 Stream API 对于现代 Java 开发至关重大。