0Pricing
Java Academy · 课时

常见陷阱

避免 Stream 使用中的常见错误:重复使用流、隐藏的副作用,以及并行处理与可变状态结合带来的问题。

常见陷阱 是 CoddyKit 上的免费 Java Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 3 节课。

简介

流功能强大,但也存在一些陷阱:重复使用流、隐藏的副作用,以及将并行处理与可变状态混在一起。

一次性流

流是一次性的:执行终止操作(forEach、collect、reduce)后,就不能再次使用。

代码:重复使用错误

执行终止操作后,流就已被消耗;尝试再次使用它会抛出 IllegalStateException。

import java.util.*;import java.util.stream.*;public class Main {
  public static void main(String[] args) {
    List<Integer> nums = Arrays.asList(1, 2, 3);
    Stream<Integer> s = nums.stream();
    s.forEach(System.out::println); // terminal
    try {
      s.forEach(System.out::println); // reuse -> IllegalStateException
    } catch (IllegalStateException e) {
      System.out.println("Oops: " + e.getMessage());
    }
  }
}

副作用

请避免在 map/filter 中产生副作用,例如修改外部列表。请优先使用纯函数,并在最后调用 collect()。

代码:副作用与收集

在流程中修改状态很脆弱。使用 collect() 的版本更加清晰和安全。

import java.util.*;import java.util.stream.*;public class Main {
  public static void main(String[] args) {
    List<Integer> nums = Arrays.asList(1,2,3);
    // Pitfall: mutating external list from map/forEach
    List<Integer> out = new ArrayList<>();
    nums.stream().map(n -> { out.add(n*n); return n*n; }).forEach(x -> {});
    System.out.println("With side effects: " + out);

    // Better: use collect to build the result
    List<Integer> squares = nums.stream().map(n -> n*n).collect(Collectors.toList());
    System.out.println("With collect: " + squares);
  }
}

代码:并行处理与可变状态

并行流与可变容器结合使用可能导致竞态条件。请优先使用能够处理并发的 collect()。

import java.util.*;public class Main {
  public static void main(String[] args) {
    List<Integer> nums = java.util.Arrays.asList(1,2,3,4,5);
    // Pitfall: adding to a normal ArrayList from parallel pipeline (unsafe)
    List<Integer> unsafe = new ArrayList<>();
    nums.parallelStream().forEach(n -> unsafe.add(n)); // may be unsafe
    System.out.println("Parallel add to ArrayList (unsafe demo): " + unsafe);

    // Safer: use built-in collectors
    List<Integer> safe = nums.parallelStream().map(n -> n).collect(java.util.stream.Collectors.toList());
    System.out.println("Collected safely: " + safe);
  }
}

陷阱检查

快速检查:以下哪项是初学者常见的流陷阱?

回顾

回顾:1)流只能使用一次。2)避免在流程中产生副作用。3)不要将并行流与不安全的可变状态混用。

常见问题解答

「常见陷阱」课时是免费的吗?

是的 — 「常见陷阱」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 3 节课。

「常见陷阱」这节课中我会学到什么?

避免 Stream 使用中的常见错误:重复使用流、隐藏的副作用,以及并行处理与可变状态结合带来的问题。 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Java Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。

「常见陷阱」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Java Academy 课中编写并运行代码吗?

能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 排序与短路求值
  2. 并行流基础
  3. 常见陷阱
← 返回 Java Academy