slug
type
status
category
date
summary
tags
password
icon
Project 4.9.10.
我直接按代码从上到下来,一行一行、块一块解释,每一处都说清楚“这是什么 + 它在这里干嘛”。
import关键字:告诉 Java 编译器,要使用其他包里的类。
java.util:Java 标准库里的一个工具包,里面有ArrayList、Scanner等很多实用类。
- :表示导入
java.util这个包中所有公共类。
- 本代码真正用到的是:
ArrayList。
public:这个类可以被项目中其他任何类访问。
class WordPairsList:定义一个名为WordPairsList的类,用来“存放一堆 WordPair 对象的列表”。
{:类体的开始。
private:访问权限修饰符。allPairs只能在WordPairsList这个类内部使用,外部类不能直接访问。
ArrayList<WordPair>:一个动态数组,里面每个元素的类型是WordPair。
allPairs:变量名,表示“所有单词对”的列表。
- 此时只是声明变量,还没有真正
new出对象。
public:构造方法可以被外部代码调用。
WordPairsList(...):这是类的构造方法,名字必须和类名相同。
- 参数
String[] words:调用构造方法时传入的一个字符串数组,比如{"Hi", "there", "Tyler", "Sam"}。
- 这个构造方法的任务:根据
words数组里的单词,生成所有的有序单词对,并存到allPairs里。
- 注释:说明下面这行的作用——初始化
allPairs。
new ArrayList<WordPair>():创建一个空的ArrayList,里面将来存WordPair对象。
allPairs = ...:把新创建的 ArrayList 赋值给成员变量allPairs。
- 现在
allPairs变成一个可用的、空的列表。
- 注释:说明接下来是嵌套循环,用来生成所有有序对
(i, j),并要求i < j。
for (int i = 0; i < words.length; i++):int i = 0:外层循环计数器,从 0 开始。i < words.length:当i小于数组长度时继续循环。i++:每次循环结束后i自增 1。
- 外层循环负责选择“第一个单词”的下标。
- 这是内层循环:
int j = i + 1:内层从i + 1开始,保证j > i,避免 (Hi,Hi) 这种同位置或重复顺序。j < words.length:当j在数组范围内就继续。j++:每次循环结束后j自增 1。
- 内层循环负责选择“第二个单词”的下标。
- 整体效果:枚举所有下标组合
(i, j),其中0 ≤ i < j < length。
new WordPair(words[i], words[j]):- 创建一个新的
WordPair对象。 words[i]:第一个单词。words[j]:第二个单词。
allPairs.add(...):- 把新创建的
WordPair对象加入到allPairs这个ArrayList的末尾。
- 也就是说,每找到一对
(i, j)(i < j),就生成一个(words[i], words[j])的单词对。
- 这三个
}分别对应: - 最内层
for循环结束。 - 外层
for循环结束。 - 构造方法
WordPairsList结束。
- 构造方法执行完之后,
allPairs已经装好了:包含由words数组所有元素组成的有序单词对。
public:外部可以调用这个方法。
int numMatches():定义一个返回int类型的成员方法,用来计算“匹配的单词对”的数量。
- “匹配”的含义在下面几行里:
getFirst()和getSecond()相等的 pair。
- 定义一个整型变量
count,初始为 0。
- 用来统计满足条件(两个单词相同)的
WordPair数量。
- 这是一个增强 for 循环(for-each):
WordPair wp:循环变量,每次循环里是一个WordPair对象。: allPairs:从allPairs这个ArrayList中依次取出每个元素。
- 等价于“对列表中的每个单词对
wp,做以下事情”。
wp.getFirst():调用WordPair的getFirst()方法,得到第一个单词(word1)。
wp.getSecond():调用getSecond()方法,得到第二个单词(word2)。
.equals(...):字符串比较内容是否相同(不能用==来比内容)。
- 如果两个字符串相等,说明这个 pair 是
(word, word)这种形态,就属于“匹配”。
count++:遇到一个匹配的 pair,就把计数加 1。
}:结束 for-each 循环。
return count;:返回匹配的单词对数量。
- 最后的
}:结束numMatches方法。
- 重写
toString()方法: - 当你打印一个
WordPairsList对象时,会自动调用toString()。
allPairs.toString():- 调用
ArrayList的toString(),会把列表里的所有元素按[elem1, elem2, ...]的形式拼成一个字符串。 - 每个元素本身会调用自己类的
toString(),因此会打印出一个个"(word1, word2)"。
public:主方法可以被 JVM 调用。
static:属于类本身,不需要先创建WordPairsList对象就可以执行。
void:方法没有返回值。
main(String[] args):Java 程序入口方法。
- 声明并初始化一个字符串数组
words,有 4 个元素: words[0] = "Hi"words[1] = "there"words[2] = "Tyler"words[3] = "Sam"
new WordPairsList(words):- 调用前面定义的构造方法,把
words传进去。 - 在构造方法内部会生成所有
i < j的单词对,并存入allPairs。
list:这是一个WordPairsList类型的对象引用,指向新创建的对象。
- 打印
list对象。
- 实际上会调用
list.toString()方法。
- 最终输出形如:
[(Hi, there), (Hi, Tyler), (Hi, Sam), (there, Tyler), (there, Sam), (Tyler, Sam)]
- 这几行是注释。
- 提示你:如果把前面的
//去掉,就会执行这行代码。
- 这行代码会:
- 调用
list.numMatches()计算匹配的 pair 数量。 - 拼接成字符串输出。
- 在当前这个
words数组中,没有重复的单词,所以numMatches()应该返回 0。
- 结束
main方法。
- 结束
WordPairsList类。
- 定义另一个类
WordPair,没有写public,说明它是包可见性:在同一个包里可以访问。
- 这个类表示“一个单词对”,即
(word1, word2)。
- 声明两个私有成员变量:
word1:第一个单词。word2:第二个单词。
private:只能在WordPair类内部访问,符合封装原则。
- 构造方法:
- 参数
word1和word2是传进来的两个单词。
this.word1 = word1;:- 左边
this.word1是成员变量,右边word1是参数。 - 把传进来的值赋给当前对象的成员变量。
- 同理
this.word2 = word2;。
- 公共方法
getFirst(): - 返回第一个单词
word1。
- 这是一个 getter,用于从外部读取私有成员变量。
- 公共方法
getSecond(): - 返回第二个单词
word2。
- 重写
toString()方法: - 定义这个对象在打印时的字符串形式。
return "(" + word1 + ", " + word2 + ")";:- 返回形如
(Hi, there)的字符串。
- 最后的
}:结束WordPair类的定义。
Activity 4.9.9.
我直接按从上到下、几乎每一行给你讲一遍在干嘛,也顺便帮你串一下整体逻辑。
import语句:告诉 Java 编译器“我要用java.util这个包里的类”。
java.util里有很多集合类,比如ArrayList,HashMap等。
- 表示导入这个包中所有公共类。
在这段代码里,我们实际用到的是:
ArrayList。- 定义一个公共类
WordPairTest。
- 按照 Java 规范:一个 .java 文件里如果有 public 类,那么文件名必须和这个类名完全一致,所以这个文件应该叫
WordPairTest.java。
- 大括号
{表示这个类的开始。
public:主方法对外是公开的,JVM 可以调用它。
static:是类方法,不需要创建WordPairTest对象就可以直接用类名调用。JVM 启动程序时就是直接调用这个静态方法。
void:表示这个方法没有返回值。
main:Java 程序的入口方法,固定写法。
String[] args:命令行参数(字符串数组),这段代码里没用到。
{:主方法体的开始。
- 这一行是注释(
//开头),给人看的,不会被编译器执行。
- 中文意思:创建一个存放
WordPair对象的ArrayList,名字叫pairs。
ArrayList<WordPair>:这是一个泛型集合,表示“一个ArrayList,里面存的是WordPair类型的对象”。- 和
ArrayList<String>类似,只不过这里存的是你自定义的WordPair。
pairs:变量名,这个变量引用一个ArrayList对象。
=:赋值运算符,把右边new出来的对象赋给左边的变量。
new ArrayList<WordPair>():new:在堆内存中创建一个新的ArrayList对象。<WordPair>再写一遍,是旧一点的写法。也可以写成:
- 整句含义:创建一个空的、用来装
WordPair对象的动态数组,并用变量pairs引用它。
这一行做了两件事:
new WordPair("hi", "there")- 调用了下面定义的
WordPair构造方法,传入两个字符串"hi"和"there"。 - 会创建一个
WordPair对象,其中: word1="hi"word2="there"
pairs.add( … )add是ArrayList的方法,用来把一个元素放到列表的末尾。- 这里就是:把刚刚创建好的
WordPair("hi", "there")放进pairs这个列表里。
- 同理,再创建一个
WordPair对象: word1="hi"word2="bye"
- 再把这个对象添加到
pairs的后面。
- 此时
pairs里有两个元素(两个WordPair对象): (hi, there)(hi, bye)
System.out.println(...):向控制台打印内容。
- 当你打印一个
ArrayList时,ArrayList会调用: - 每个元素的
toString()方法来生成字符串, - 然后用逗号+空格分隔,外面再加一对方括号
[]。
- 我们的
WordPair类里重写了toString(),返回"(" + word1 + ", " + word2 + ")"。
- 所以打印结果会是:
- 这两个右大括号依次关闭:
- 最里层
}:结束main方法。 - 外层
}:结束WordPairTest类定义。
从这里开始是第二个类的定义:
- 定义一个类
WordPair,注意这里 没有写public,所以它是包可见(同一个包里可以访问,别的包看不到)。
- 这个类用来表示“一对单词”。
- 定义两个实例变量(成员变量):
word1:存第一 个单词。word2:存第二个单词。
private:封装性,这两个变量外部类不能直接访问,只能通过方法(getter)访问。
String:表示用字符串类型存单词。
这是
WordPair 的构造方法:- 方法名和类名相同
WordPair,说明这是构造器。
public:外部可以用new WordPair(...)来创建对象。
- 参数列表:
(String word1, String word2): - 调用构造方法时需要提供两个字符串。
- 方法体内部:
this.word1 = word1;- 左边
this.word1:当前对象的成员变量word1。 - 右边
word1:方法参数。 - 等式含义:把传进来的参数赋值给当前对象的成员变量。
this.word2 = word2;同理。
- 为何要用
this? - 因为参数名和成员变量名相同,用
this.word1区分“对象里的那个”。
- 这是一个 getter 方法。
public:外部可以调用。
- 返回类型是
String。
- 方法名
getFirst():语义上表示“获得第一个单词”。
- 方法体只有一句:
return word1; - 返回当前对象的
word1。
- 同样是 getter。
- 返回当前对象的
word2。
public String toString():- 这是从
Object类继承来的方法,这里进行了重写(override)。 - 当你打印对象(
System.out.println(obj))或者把对象拼接到字符串时,会自动调用toString()。
- 方法体:
- 用字符串拼接,把两个单词包装成一个形如
(hi, there)的字符串。 - 如果
word1 = "hi",word2 = "there",那么toString()返回:"(hi, there)"。
- 最后的
}:结束WordPair类。
总结一下整体运行流程
- 程序从
main方法开始执行。
- 创建一个
ArrayList<WordPair>叫pairs。
- 向
pairs里添加两个WordPair对象: "hi", "there""hi", "bye"
System.out.println(pairs):ArrayList调用每个WordPair的toString(),得到:(hi, there)和(hi, bye)。- 然后组合成:
[(hi, there), (hi, bye)]打印出来。
- 作者:现代数学启蒙
- 链接:https://www.math1234567.com/article/codeexplained49
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章










