news 2026/2/26 18:22:45

Java 8 Stream API 深度解析:从入门到精通

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 8 Stream API 深度解析:从入门到精通

一、Stream API 概述

1.1 什么是 Stream API

Java 8 引入的 Stream API 是处理集合数据的革命性特性,它允许开发者以声明式的方式处理数据集合,支持并行操作,极大地提高了代码的可读性和执行效率。

核心特点:

  • 声明式编程:描述"做什么"而非"如何做"

  • 函数式风格:支持 Lambda 表达式和方法引用

  • 惰性求值:中间操作延迟执行

  • 可并行化:自动利用多核处理器

  • 内部迭代:无需显式迭代器

1.2 Stream 与传统集合的区别

java

// 传统方式:外部迭代 List<String> filteredNames = new ArrayList<>(); for (String name : names) { if (name.startsWith("A")) { filteredNames.add(name.toUpperCase()); } } // Stream API:内部迭代 List<String> filteredNames = names.stream() .filter(name -> name.startsWith("A")) .map(String::toUpperCase) .collect(Collectors.toList());

二、Stream 创建方式大全

2.1 从集合创建

java

// 1. 从 List 创建 List<String> list = Arrays.asList("a", "b", "c"); Stream<String> streamFromList = list.stream(); // 2. 从 Set 创建 Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3)); Stream<Integer> streamFromSet = set.stream(); // 3. 从 Map 创建 Map<String, Integer> map = new HashMap<>(); map.put("a", 1); map.put("b", 2); Stream<Map.Entry<String, Integer>> streamFromMap = map.entrySet().stream();

2.2 从数组创建

java

// 基本类型数组 int[] intArray = {1, 2, 3, 4, 5}; IntStream intStream = Arrays.stream(intArray); // 对象数组 String[] stringArray = {"a", "b", "c"}; Stream<String> stringStream = Arrays.stream(stringArray); // 使用 Stream.of Stream<String> streamOf = Stream.of("a", "b", "c");

2.3 特殊 Stream 创建

java

// 1. 空 Stream Stream<String> emptyStream = Stream.empty(); // 2. 无限流 // 生成规律序列 Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2) .limit(10); // 生成随机数 Stream<Double> generateStream = Stream.generate(Math::random) .limit(5); // 3. 范围 Stream IntStream rangeStream = IntStream.range(1, 10); // 1-9 IntStream rangeClosedStream = IntStream.rangeClosed(1, 10); // 1-10

2.4 从文件创建

java

// 读取文件所有行 try (Stream<String> lines = Files.lines(Paths.get("data.txt"))) { lines.forEach(System.out::println); } catch (IOException e) { e.printStackTrace(); } // 读取大文件 - 并行处理 try (Stream<String> parallelLines = Files.lines(Paths.get("bigfile.txt")).parallel()) { long count = parallelLines .filter(line -> line.contains("error")) .count(); System.out.println("Error lines: " + count); }

2.5 从 I/O 流创建

java

// 从 BufferedReader 创建 try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) { Stream<String> lines = reader.lines(); // 处理逻辑 } // 从 Pattern 创建 Pattern pattern = Pattern.compile(","); Stream<String> splitStream = pattern.splitAsStream("a,b,c,d");

三、中间操作详解

3.1 筛选操作

java

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 1. filter - 过滤 List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); // 2. distinct - 去重 List<Integer> withDuplicates = Arrays.asList(1, 2, 2, 3, 3, 3); List<Integer> distinctNumbers = withDuplicates.stream() .distinct() .collect(Collectors.toList()); // 3. limit - 限制数量 List<Integer> firstThree = numbers.stream() .limit(3) .collect(Collectors.toList()); // 4. skip - 跳过元素 List<Integer> skipFirstThree = numbers.stream() .skip(3) .collect(Collectors.toList()); // 5. takeWhile (Java 9+) - 遇到不符合条件的停止 // List<Integer> takeWhile = numbers.stream() // .takeWhile(n -> n < 5) // .collect(Collectors.toList()); // 6. dropWhile (Java 9+) - 丢弃符合条件的直到遇到第一个不符合的 // List<Integer> dropWhile = numbers.stream() // .dropWhile(n -> n < 5) // .collect(Collectors.toList());

3.2 映射操作

java

List<String> words = Arrays.asList("Java", "Stream", "API", "Example"); // 1. map - 一对一映射 List<Integer> wordLengths = words.stream() .map(String::length) .collect(Collectors.toList()); // 2. flatMap - 一对多映射,扁平化 List<String> sentences = Arrays.asList("Hello World", "Java Stream API"); List<String> allWords = sentences.stream() .flatMap(sentence -> Arrays.stream(sentence.split(" "))) .collect(Collectors.toList()); // 3. mapToInt/Long/Double - 转换为基本类型流 IntStream lengths = words.stream() .mapToInt(String::length); double averageLength = lengths.average().orElse(0); // 4. boxed - 基本类型流装箱 IntStream intStream = IntStream.of(1, 2, 3); Stream<Integer> boxedStream = intStream.boxed();

3.3 排序操作

java

List<Person> persons = Arrays.asList( new Person("Alice", 25), new Person("Bob", 30), new Person("Charlie", 20) ); // 1. 自然排序 List<String> sortedNames = persons.stream() .map(Person::getName) .sorted() .collect(Collectors.toList()); // 2. 自定义比较器 List<Person> sortedByAge = persons.stream() .sorted(Comparator.comparingInt(Person::getAge)) .collect(Collectors.toList()); // 3. 多重排序 List<Person> multiSorted = persons.stream() .sorted(Comparator.comparing(Person::getName) .thenComparingInt(Person::getAge)) .collect(Collectors.toList()); // 4. 逆序 List<Person> reverseSorted = persons.stream() .sorted(Comparator.comparing(Person::getAge).reversed()) .collect(Collectors.toList());

3.4 窥视操作(peek)

java

// peek - 调试用,不影响流 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());

3.5 转换操作

java

// 1. 转换为数组 String[] array = words.stream().toArray(String[]::new); // 2. 转换为 Iterator Iterator<String> iterator = words.stream().iterator(); // 3. 转换为 Spliterator Spliterator<String> spliterator = words.stream().spliterator();

四、终端操作详解

4.1 匹配操作

java

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // 1. allMatch - 所有元素都匹配 boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0); // false // 2. anyMatch - 任意元素匹配 boolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0); // true // 3. noneMatch - 没有元素匹配 boolean noneNegative = numbers.stream().noneMatch(n -> n < 0); // true // 4. findFirst - 返回第一个元素 Optional<Integer> first = numbers.stream().findFirst(); // 5. findAny - 返回任意元素(并行流中更高效) Optional<Integer> any = numbers.parallelStream().findAny();

4.2 归约操作

java

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); // 1. reduce - 累加 Optional<Integer> sum = numbers.stream() .reduce((a, b) -> a + b); // 等价于 Integer sum2 = numbers.stream().reduce(0, Integer::sum); // 2. 复杂归约 - 求和、求积 int product = numbers.stream() .reduce(1, (a, b) -> a * b); // 3. 字符串连接 List<String> strings = Arrays.asList("Hello", " ", "World", "!"); String concatenated = strings.stream() .reduce("", (a, b) -> a + b); // 4. 并行流归约 int parallelSum = numbers.parallelStream() .reduce(0, Integer::sum, Integer::sum);

4.3 收集操作

java

List<Person> persons = Arrays.asList( new Person("Alice", 25, "New York"), new Person("Bob", 30, "London"), new Person("Charlie", 25, "New York"), new Person("David", 35, "London") ); // 1. 转换为 List List<String> names = persons.stream() .map(Person::getName) .collect(Collectors.toList()); // 2. 转换为 Set Set<String> cities = persons.stream() .map(Person::getCity) .collect(Collectors.toSet()); // 3. 转换为 Map Map<String, Integer> nameToAge = persons.stream() .collect(Collectors.toMap( Person::getName, Person::getAge, (existing, replacement) -> existing // 处理键冲突 )); // 4. 分组 Map<String, List<Person>> personsByCity = persons.stream() .collect(Collectors.groupingBy(Person::getCity)); // 5. 多级分组 Map<String, Map<Integer, List<Person>>> personsByCityAndAge = persons.stream() .collect(Collectors.groupingBy( Person::getCity, Collectors.groupingBy(Person::getAge) )); // 6. 分区 Map<Boolean, List<Person>> partitioned = persons.stream() .collect(Collectors.partitioningBy(p -> p.getAge() > 30)); // 7. 连接字符串 String allNames = persons.stream() .map(Person::getName) .collect(Collectors.joining(", ", "[", "]")); // 8. 统计汇总 IntSummaryStatistics ageStats = persons.stream() .collect(Collectors.summarizingInt(Person::getAge)); System.out.println("Average age: " + ageStats.getAverage()); System.out.println("Max age: " + ageStats.getMax()); // 9. 自定义收集器 List<String> customCollected = persons.stream() .map(Person::getName) .collect(Collector.of( ArrayList::new, // Supplier ArrayList::add, // Accumulator (left, right) -> { // Combiner left.addAll(right); return left; }, Collector.Characteristics.IDENTITY_FINISH ));

4.4 数值统计

java

IntStream intStream = IntStream.of(1, 2, 3, 4, 5); // 1. 求和 int sum = intStream.sum(); // 2. 平均值 double average = IntStream.of(1, 2, 3, 4, 5).average().orElse(0); // 3. 最大值 int max = IntStream.of(1, 2, 3, 4, 5).max().orElse(0); // 4. 最小值 int min = IntStream.of(1, 2, 3, 4, 5).min().orElse(0); // 5. 计数 long count = IntStream.of(1, 2, 3, 4, 5).count(); // 6. 使用 summaryStatistics 一次性获取 IntSummaryStatistics stats = IntStream.of(1, 2, 3, 4, 5).summaryStatistics();

五、并行流高级技巧

5.1 创建并行流

java

// 1. 从集合创建并行流 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); Stream<Integer> parallelStream = numbers.parallelStream(); // 2. 将顺序流转为并行流 Stream<Integer> parallel = numbers.stream().parallel(); // 3. 将并行流转为顺序流 Stream<Integer> sequential = parallelStream.sequential();

5.2 并行流性能优化

java

// 1. 基准测试对比 List<Integer> largeList = IntStream.range(0, 1_000_000) .boxed() .collect(Collectors.toList()); long startTime = System.currentTimeMillis(); long sequentialSum = largeList.stream() .mapToInt(Integer::intValue) .sum(); long sequentialTime = System.currentTimeMillis() - startTime; startTime = System.currentTimeMillis(); long parallelSum = largeList.parallelStream() .mapToInt(Integer::intValue) .sum(); long parallelTime = System.currentTimeMillis() - startTime; System.out.printf("Sequential time: %dms, Parallel time: %dms%n", sequentialTime, parallelTime); // 2. 注意点:共享状态问题 List<Integer> sharedList = new ArrayList<>(); IntStream.range(0, 10000).parallel() .forEach(sharedList::add); // 错误!非线程安全 // 正确方式 List<Integer> safeList = IntStream.range(0, 10000).parallel() .boxed() .collect(Collectors.toList());

5.3 并行流的分治策略

java

// 自定义 ForkJoinPool ForkJoinPool customPool = new ForkJoinPool(4); long result = customPool.submit(() -> IntStream.range(1, 1_000_000) .parallel() .filter(n -> n % 2 == 0) .sum() ).get();

六、高级应用场景

6.1 流式查询

java

class Order { private String customer; private double amount; private LocalDate date; private String status; // getters and setters } List<Order> orders = // 获取订单数据 // 复杂查询示例 Map<String, Double> monthlyRevenue = orders.stream() .filter(o -> o.getStatus().equals("COMPLETED")) .filter(o -> o.getDate().isAfter(LocalDate.now().minusMonths(12))) .collect(Collectors.groupingBy( o -> o.getDate().getMonth().toString(), Collectors.summingDouble(Order::getAmount) )); // 找出最大订单 Optional<Order> largestOrder = orders.stream() .max(Comparator.comparingDouble(Order::getAmount)); // 客户统计 Map<String, Long> customerOrderCount = orders.stream() .collect(Collectors.groupingBy( Order::getCustomer, Collectors.counting() ));

6.2 流式数据转换

java

// JSON 数据转换 List<Map<String, Object>> jsonData = // 从API获取 // 转换为特定对象 List<User> users = jsonData.stream() .map(map -> new User( (String) map.get("name"), (Integer) map.get("age"), (String) map.get("email") )) .collect(Collectors.toList()); // 复杂数据转换 Map<String, List<String>> groupedData = jsonData.stream() .flatMap(map -> ((List<Map<String, String>>) map.get("items")).stream()) .collect(Collectors.groupingBy( item -> item.get("category"), Collectors.mapping(item -> item.get("name"), Collectors.toList()) ));

6.3 流式文件处理

java

// 处理大文件 try (Stream<String> lines = Files.lines(Paths.get("large_file.log"))) { Map<String, Long> errorCount = lines .parallel() .filter(line -> line.contains("ERROR")) .map(line -> line.split(" ")[0]) // 提取日期 .collect(Collectors.groupingBy( date -> date, Collectors.counting() )); // 输出每天的错误数 errorCount.forEach((date, count) -> System.out.println(date + ": " + count)); } // 文件内容分析 Path directory = Paths.get("src/main/java"); try (Stream<Path> paths = Files.walk(directory)) { Map<String, Long> fileStats = paths .filter(Files::isRegularFile) .filter(p -> p.toString().endsWith(".java")) .collect(Collectors.toMap( Path::toString, p -> { try { return Files.lines(p).count(); } catch (IOException e) { return 0L; } } )); }

6.4 流式算法实现

java

// 1. 斐波那契数列 Stream<BigInteger> fibonacci = Stream.iterate( new BigInteger[]{BigInteger.ZERO, BigInteger.ONE}, t -> new BigInteger[]{t[1], t[0].add(t[1])} ).map(t -> t[0]); // 2. 素数筛选 IntStream primes = IntStream.rangeClosed(2, 1000) .filter(n -> IntStream.rangeClosed(2, (int) Math.sqrt(n)) .noneMatch(i -> n % i == 0)); // 3. 分页查询模拟 class Pagination { static <T> List<T> getPage(List<T> source, int page, int size) { return source.stream() .skip((page - 1) * size) .limit(size) .collect(Collectors.toList()); } }

七、性能优化与最佳实践

7.1 性能优化技巧

java

// 1. 避免装箱拆箱 // 差 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); int sum = list.stream() .mapToInt(Integer::intValue) // 这里其实在拆箱 .sum(); // 好 IntStream intStream = IntStream.rangeClosed(1, 1000000); int sum = intStream.sum(); // 2. 短路操作优化 Optional<String> result = largeList.stream() .filter(s -> s.startsWith("A")) .findFirst(); // 找到第一个就停止 // 3. 预分配大小(对于 ArrayList) List<String> collected = stream .collect(Collectors.toCollection(() -> new ArrayList<>(expectedSize))); // 4. 合并操作 // 差:多次遍历 long count = list.stream().filter(condition1).count(); List<String> filtered = list.stream().filter(condition2).collect(toList()); // 好:一次遍历 Map<Boolean, List<String>> partitioned = list.stream() .collect(Collectors.partitioningBy(condition1)); long count = partitioned.get(true).size(); List<String> filtered = partitioned.get(false).stream() .filter(condition2) .collect(toList());

7.2 调试技巧

java

// 1. 使用 peek 调试 List<String> result = stream .peek(e -> System.out.println("Before filter: " + e)) .filter(s -> s.length() > 3) .peek(e -> System.out.println("After filter: " + e)) .map(String::toUpperCase) .collect(Collectors.toList()); // 2. 异常处理 List<Integer> processed = numbers.stream() .map(n -> { try { return processNumber(n); } catch (Exception e) { return defaultValue; } }) .collect(Collectors.toList()); // 3. 性能监控 long start = System.nanoTime(); List<String> result = stream .parallel() .map(this::expensiveOperation) .collect(Collectors.toList()); long duration = System.nanoTime() - start;

7.3 最佳实践

java

// 1. 保持流操作无状态 // 错误:使用外部变量 AtomicInteger counter = new AtomicInteger(); List<String> bad = stream .map(s -> s + counter.getAndIncrement()) .collect(Collectors.toList()); // 正确:使用 zipWithIndex 模式 List<String> good = IntStream.range(0, list.size()) .mapToObj(i -> list.get(i) + i) .collect(Collectors.toList()); // 2. 避免副作用 // 错误:修改外部状态 List<String> results = new ArrayList<>(); stream.forEach(results::add); // 副作用 // 正确:使用 collect List<String> results = stream.collect(Collectors.toList()); // 3. 优先使用原始类型流 // 差 Stream<Integer> boxedStream = Stream.of(1, 2, 3, 4, 5); // 好 IntStream intStream = IntStream.of(1, 2, 3, 4, 5); // 4. 适当使用并行流 // 适合并行:大数据量、计算密集 long sum = largeList.parallelStream() .mapToLong(this::expensiveCalculation) .sum(); // 不适合并行:小数据量、IO密集 List<String> lines = smallList.stream() .map(this::ioBoundOperation) .collect(Collectors.toList());

八、常见陷阱与解决方案

8.1 流已被操作或关闭

java

Stream<String> stream = list.stream(); // 错误:流被重复使用 List<String> result1 = stream.filter(s -> s.startsWith("A")).collect(toList()); List<String> result2 = stream.filter(s -> s.startsWith("B")).collect(toList()); // 异常! // 解决方案1:重新创建流 Supplier<Stream<String>> streamSupplier = () -> list.stream(); List<String> result1 = streamSupplier.get().filter(s -> s.startsWith("A")).collect(toList()); List<String> result2 = streamSupplier.get().filter(s -> s.startsWith("B")).collect(toList()); // 解决方案2:一次处理多个条件 Map<Boolean, List<String>> partitioned = list.stream() .collect(Collectors.partitioningBy(s -> s.startsWith("A"))); List<String> startsWithA = partitioned.get(true); List<String> others = partitioned.get(false);

8.2 无限流处理

java

// 错误:忘记限制无限流 Stream.iterate(0, i -> i + 1) .forEach(System.out::println); // 无限执行 // 正确:使用 limit 或短路操作 Stream.iterate(0, i -> i + 1) .limit(100) .forEach(System.out::println); // 或者使用 takeWhile(Java 9+) // Stream.iterate(0, i -> i + 1) // .takeWhile(i -> i < 100) // .forEach(System.out::println);

8.3 空指针处理

java

List<String> list = Arrays.asList("a", null, "c"); // 错误:可能抛出 NPE List<String> upper = list.stream() .map(String::toUpperCase) // 这里会 NPE .collect(Collectors.toList()); // 解决方案1:过滤 null List<String> upper = list.stream() .filter(Objects::nonNull) .map(String::toUpperCase) .collect(Collectors.toList()); // 解决方案2:使用 Optional List<Optional<String>> result = list.stream() .map(Optional::ofNullable) .map(opt -> opt.map(String::toUpperCase)) .collect(Collectors.toList());

九、扩展与集成

9.1 与 Optional 集成

java

// 1. Stream of Optional List<Optional<String>> optionals = Arrays.asList( Optional.of("value1"), Optional.empty(), Optional.of("value3") ); List<String> values = optionals.stream() .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); // 2. 使用 flatMap 处理 Optional List<String> result = optionals.stream() .flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty)) .collect(Collectors.toList()); // 3. Optional 的流式操作 Optional<User> user = findUserById(1); String email = user .map(User::getProfile) .map(Profile::getEmail) .orElse("default@example.com");

9.2 自定义收集器

java

// 1. 实现复杂统计 class ComplexStats { private long count; private double sum; private double min = Double.MAX_VALUE; private double max = Double.MIN_VALUE; // 方法和构造器 } Collector<Double, ComplexStats, ComplexStats> complexCollector = Collector.of( ComplexStats::new, ComplexStats::accept, ComplexStats::combine, Collector.Characteristics.IDENTITY_FINISH ); // 2. 批处理收集器 public static <T> Collector<T, ?, List<List<T>>> batchCollector(int batchSize) { return Collector.of( ArrayList::new, (List<List<T>> batches, T item) -> { List<T> lastBatch; if (batches.isEmpty() || batches.get(batches.size() - 1).size() == batchSize) { lastBatch = new ArrayList<>(); batches.add(lastBatch); } else { lastBatch = batches.get(batches.size() - 1); } lastBatch.add(item); }, (left, right) -> { left.addAll(right); return left; } ); }

9.3 与 CompletableFuture 集成

java

// 并行异步处理 List<CompletableFuture<String>> futures = urls.stream() .map(url -> CompletableFuture.supplyAsync(() -> fetchUrl(url), executor)) .collect(Collectors.toList()); CompletableFuture<Void> allFutures = CompletableFuture.allOf( futures.toArray(new CompletableFuture[0]) ); CompletableFuture<List<String>> allResults = allFutures.thenApply(v -> futures.stream() .map(CompletableFuture::join) .collect(Collectors.toList()) );

十、实战案例集合

10.1 电商系统应用

java

class OrderService { // 计算每个用户的订单总金额 public Map<Long, Double> getUserOrderTotal(List<Order> orders) { return orders.stream() .collect(Collectors.groupingBy( Order::getUserId, Collectors.summingDouble(Order::getTotalAmount) )); } // 获取热销商品TOP10 public List<Product> getTopSellingProducts(List<Order> orders, int limit) { return orders.stream() .flatMap(order -> order.getItems().stream()) .collect(Collectors.groupingBy( OrderItem::getProductId, Collectors.summingInt(OrderItem::getQuantity) )) .entrySet().stream() .sorted(Map.Entry.<Long, Integer>comparingByValue().reversed()) .limit(limit) .map(entry -> productService.findById(entry.getKey())) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()); } // 时间段分析 public Map<LocalDate, Double> getDailyRevenue(List<Order> orders, LocalDate start, LocalDate end) { return orders.stream() .filter(order -> !order.getCreateTime().toLocalDate().isBefore(start)) .filter(order -> !order.getCreateTime().toLocalDate().isAfter(end)) .collect(Collectors.groupingBy( order -> order.getCreateTime().toLocalDate(), TreeMap::new, // 保持日期排序 Collectors.summingDouble(Order::getTotalAmount) )); } }

10.2 数据分析系统

java

class DataAnalyzer { // 数据清洗和转换 public List<CleanedData> cleanData(List<RawData> rawDataList) { return rawDataList.stream() .parallel() .filter(this::isValidData) .map(this::transformData) .filter(Objects::nonNull) .sorted(Comparator.comparing(CleanedData::getTimestamp)) .collect(Collectors.toList()); } // 异常检测 public List<Anomaly> detectAnomalies(List<DataPoint> dataPoints) { // 计算移动平均 Map<String, Double> movingAverages = calculateMovingAverages(dataPoints); return dataPoints.stream() .filter(point -> { double avg = movingAverages.getOrDefault(point.getMetric(), 0.0); return Math.abs(point.getValue() - avg) > 3 * calculateStdDev(point.getMetric()); }) .map(point -> new Anomaly(point, "Deviation from mean")) .collect(Collectors.toList()); } // 实时数据流处理 public void processStream(Stream<Event> eventStream) { eventStream .windowed(Duration.ofMinutes(1)) // 假设有窗口函数 .flatMap(window -> window .collect(Collectors.groupingBy( Event::getType, Collectors.counting() )) .entrySet().stream() .map(entry -> new Metric("events.per.minute", entry.getKey(), entry.getValue())) ) .forEach(this::sendToMonitoring); } }

10.3 文件处理系统

java

class FileProcessor { // 批量文件处理 public Map<String, FileStats> processDirectory(Path directory) throws IOException { try (Stream<Path> paths = Files.walk(directory)) { return paths .filter(Files::isRegularFile) .parallel() .collect(Collectors.toMap( Path::toString, this::analyzeFile, (existing, replacement) -> existing )); } } private FileStats analyzeFile(Path file) { try { long lineCount = Files.lines(file).count(); long wordCount = Files.lines(file) .flatMap(line -> Arrays.stream(line.split("\\s+"))) .count(); long size = Files.size(file); return new FileStats(lineCount, wordCount, size); } catch (IOException e) { return new FileStats(0, 0, 0); } } // 日志分析 public LogAnalysis analyzeLogs(Path logFile) throws IOException { try (Stream<String> lines = Files.lines(logFile)) { return lines .parallel() .collect(Collectors.collectingAndThen( Collectors.toList(), list -> { long totalLines = list.size(); long errorCount = list.stream() .filter(line -> line.contains("ERROR")) .count(); long warningCount = list.stream() .filter(line -> line.contains("WARNING")) .count(); Map<String, Long> errorByType = list.stream() .filter(line -> line.contains("ERROR")) .map(this::extractErrorType) .collect(Collectors.groupingBy( Function.identity(), Collectors.counting() )); return new LogAnalysis(totalLines, errorCount, warningCount, errorByType); } )); } } }

总结

Java 8 Stream API 是一个强大而灵活的工具,它彻底改变了我们处理集合数据的方式。通过本文的详细讲解,您应该已经掌握了:

  1. Stream 的核心概念:理解流与集合的区别,掌握声明式编程的优势

  2. 完整的操作链:从创建、中间操作到终端操作的完整流程

  3. 并行处理能力:充分利用多核处理器的性能优势

  4. 高级技巧:各种实际应用场景的最佳实践

  5. 性能优化:避免常见陷阱,编写高效的流式代码

Stream API 的学习曲线可能较陡峭,但一旦掌握,它将极大地提升您的编程效率和代码质量。记住实践是最好的老师,多在实际项目中应用这些技巧,您将更快地成为 Stream API 的大师。

最后提醒

  • 优先考虑代码可读性,不要过度使用复杂的流操作

  • 注意并行流的适用场景,不是所有情况都适合并行化

  • 及时处理资源,确保流在使用后被正确关闭

  • 保持函数式编程的纯净性,避免副作用

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/26 0:31:29

ReentrantLock(重入锁)基于AQS的源码实现

一、先搞懂核心基础&#xff1a;ReentrantLock和AQS的关系 你可以把AQS&#xff08;AbstractQueuedSynchronizer&#xff09; 理解成一个“同步组件的通用骨架”——它提前写好了同步队列管理、线程阻塞/唤醒的核心逻辑&#xff0c;只留了几个“钩子方法”&#xff08;比如tryA…

作者头像 李华
网站建设 2026/2/25 21:15:27

C++ 观察者模式

&#x1f3af; 观察者模式协作关系说明 01、资源获取 >>> 通过网盘分享的文件&#xff1a;CXX观察者模式observer_pattern 链接: https://pan.baidu.com/s/15_ev6Y-ZL0cQjrfIrA7Y9Q?pwdubrb 提取码: ubrb &#x1f4d6; 模式概述 观察者模式&#xff08;Observ…

作者头像 李华
网站建设 2026/2/24 22:37:49

GTE+SeqGPT企业应用案例:某IT公司内部技术知识库智能问答系统落地纪实

GTESeqGPT企业应用案例&#xff1a;某IT公司内部技术知识库智能问答系统落地纪实 1. 为什么这家IT公司决定自建知识库问答系统&#xff1f; 一家拥有300多名工程师的中型IT服务公司&#xff0c;过去三年里积累的技术文档已超过12万份——从服务器部署手册、API接口说明、故障…

作者头像 李华
网站建设 2026/2/24 3:39:02

DASD-4B-Thinking企业应用实战:vLLM服务化部署+Chainlit智能助手构建

DASD-4B-Thinking企业应用实战&#xff1a;vLLM服务化部署Chainlit智能助手构建 1. 为什么需要一个“会思考”的小模型&#xff1f; 你有没有遇到过这样的场景&#xff1a; 需要快速验证一段数学推导是否合理&#xff0c;但不想打开复杂IDE或等待大模型慢吞吞响应&#xff1…

作者头像 李华
网站建设 2026/2/22 21:47:36

Phi-4-mini-reasoning在ollama中效果展示:生成LaTeX公式+Markdown推理过程

Phi-4-mini-reasoning在Ollama中效果展示&#xff1a;生成LaTeX公式Markdown推理过程 1. 这个模型到底能干啥&#xff1f;先看几个真实例子 你有没有试过让AI写一段带推导步骤的数学证明&#xff1f;或者让它把一道微积分题从头到尾拆解清楚&#xff0c;每一步都配上说明&…

作者头像 李华
网站建设 2026/2/26 11:33:34

HY-MT1.5-1.8B自动驾驶场景:车载多语言交互系统集成

HY-MT1.5-1.8B自动驾驶场景&#xff1a;车载多语言交互系统集成 在智能汽车快速演进的今天&#xff0c;人车交互已不再满足于单一语音指令或固定语种响应。当用户用粤语询问导航路线、用维吾尔语查看车辆状态、用英语向后排乘客解释功能时&#xff0c;车载系统能否“听懂”“理…

作者头像 李华