正在加载...

Java 中的 Lambda

用箭头把短动作传给 forEach。在 Cue.java 中保留 public 类 Cue,加入 import java.util.ArrayList;,把 "oak" 放进带类型的列表,并调用 names.forEach(n -> System.out.println(n));。用 javac Cue.java 编译,运行 java Cue。屏幕应显示 oak。第二段演示再 add "pine",屏幕会显示 oak,然后 pine。把可选的 Streams 留给下一页。本课是传给 forEach 的 lambda,不是 Generics 的 get(0) 演示,也不是命令行 args。

一个元素,一次 lambda 打印

打开 Cue.java。保留 public 类名 Cue。若挡住 lambda 主线,删掉残留的 Bin Generics 演示、残留的 Program Arguments Flag 运行、残留的 Box Scanner 提示,以及 Shelf 历史。程序不能等待键盘输入,也不要求启动时带单词。
在文件顶部添加 import:
import java.util.ArrayList;
在 Cue.main 里构建带类型列表,添加一个词,并把 lambda 传给 forEach:
ArrayList<String> names = new ArrayList<>();
names.add("oak");
names.forEach(n -> System.out.println(n));
n -> System.out.println(n) 就是 lambda。n 是单个元素的参数名。箭头 -> 指向为该元素执行的方法体。forEach 对 "oak" 调用一次该体。屏幕显示 oak。

Cue forEach lambda prints oak

java
import java.util.ArrayList;

public class Cue {
    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        names.add("oak");
        names.forEach(n -> System.out.println(n));
    }
}

在存放 Cue.java 的文件夹里运行 javac Cue.java。花括号和分号匹配时,javac 自己不会打印一行。然后运行 java Cue — 不是 java Cue.java。只保留一个 public 类,使名称与 Cue 一致。
顺着执行走一遍。Java 从 Cue.main 开始。列表里有 "oak"。forEach 接收 lambda。对第一个(也是唯一)元素,n 是 "oak",println 写出 oak。在这种教学形态下没有人调用 get(0)。没有人从 Integer Bin 演示打印 3。没有人读取 args[0]。
看着屏幕说出初学者规则:forEach 遍历列表;lambda 是每个元素上的动作;箭头把参数与方法体分开。不要在本页发明 Streams 管道。Streams 等在下一堂可选课。不要把本教学文件里的 lambda 换成完整命名方法 — 保留箭头形式。
若你仍在残留的 Bin 文件里只看到 names.get(0) 的 oak,请改做 Cue 并保留 forEach 行。若 javac 拒绝箭头,检查是否输入了 ->,以及 lambda 是否在 forEach(...) 内。

两个元素,同一 lambda

继续用 public 类 Cue。在 forEach 之前再添加一个词:
names.add("oak");
names.add("pine");
names.forEach(n -> System.out.println(n));
再次 javac Cue.java 编译并 java Cue 运行。屏幕显示 oak,然后 pine。forEach 按顺序对每个元素各调用一次 lambda。lambda 方法体不变。只有列表长度变了。

Cue forEach lambda prints oak then pine

java
import java.util.ArrayList;

public class Cue {
    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        names.add("oak");
        names.add("pine");
        names.forEach(n -> System.out.println(n));
    }
}

再顺着执行走一遍。第一次调用:n 是 "oak",打印 oak。第二次调用:n 是 "pine",打印 pine。把两段演示当作两种教学形态。先证明单次 lambda 打印。再证明同一 lambda 作用于两个元素。两种形态共享 import、带类型列表和 n -> System.out.println(n)。
若你用 println(names) 代替 forEach 打印整个列表,会看到方括号和逗号 — 那是另一种习惯。本页坚持通过 lambda 每个元素打印一行。

Lambda 不只是 Generics,也不是 Streams

Generics 在 ArrayList<String> 里命名了元素类型。Lambda 在本页给 forEach 一个短动作,而不写单独的命名方法。Streams 会在后续可选页把更多列表步骤串起来。今天不要把这三种职责混在一个初学者文件里。
此处的 oak 是 forEach 访问的列表元素。不是 Flag 的 args[0],也不是 Scanner 的答案。当残留 Bin 仍只打印 get(0) 时,把它当历史,保留 Cue 的 forEach 行。当残留 Flag 仍要 java Flag oak 时,把那种启动习惯放一边,运行普通的 java Cue。
没有箭头时,javac 无法把动作当作 lambda。没有 forEach 时,在这种教学形态里 lambda 没有执行之处。练习时把两部分绑在一起。在那节课之前,把 .stream().map 这类 Streams 语法挡在本页之外,即便你在别的标题里见过 Stream 这个词。

Streams 前的文件夹检查

成功编译后列出文件夹。应同时看到 Cue.java 与 Cue.class。编辑源码、保存、运行 javac Cue.java,再 java Cue。若在添加 "pine" 后跳过编译,陈旧的 .class 可能仍显示旧的一行输出。
若 javac 抱怨重复的 public 类,只让 Cue 保持 public。若屏幕一行显示 [oak, pine],说明你打印了列表对象 — 改回在 lambda 内用 println 的 forEach。若没有任何输出,确认 add 在 forEach 之前执行。
不要把 Bin 的 get(0) 贴进来替换本页的 lambda。不要把 Flag 启动词贴进运行命令。可选的 lambda 作业是带箭头方法体的 forEach。

可选 Streams 之前

你可以保留 public 类 Cue、import ArrayList、add "oak"、调用 names.forEach(n -> System.out.println(n));、看到 oak,再 add "pine" 并看到 oak 然后 pine。用 javac Cue.java 编译,运行 java Cue。下一可选页是 Streams。
为清晰的 lambda 一对保留 Cue 演示。练习 forEach 时把 Bin Generics 文件挡在本页外。练习 forEach 时把 Flag Program Arguments 文件挡在本页外。在那节课之前把 Streams 工作挡在本页外。这些习惯是继续前的检查点。当单词屏幕显示 oak,或两词屏幕显示 oak 然后 pine,Lambda 已完成本课任务;若你走可选路径,已可进入 Streams。
最后再扫一遍文件夹:一个 public Cue、import 在位、带类型的 ArrayList<String>、带 n -> System.out.println(n) 的 forEach、不等待 Scanner、不要求启动词。在你保持打开的那段演示上再运行一次 javac Cue.java 和 java Cue。若屏幕仍显示 oak 或 oak 然后 pine,Lambda 形态稳固,课程可在下一页进入可选 Streams。每次阅读时优先保持一种清晰的 forEach 习惯,让同一幅地图反复教会你。

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
5
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部