slug
type
status
category
date
summary
tags
password
icon
 

Project 4.9.10.

 
 
 
我直接按代码从上到下来,一行一行、块一块解释,每一处都说清楚“这是什么 + 它在这里干嘛”。

  • import 关键字:告诉 Java 编译器,要使用其他包里的类。
  • java.util:Java 标准库里的一个工具包,里面有 ArrayListScanner 等很多实用类。
  • :表示导入 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():调用 WordPairgetFirst() 方法,得到第一个单词(word1)。
  • wp.getSecond():调用 getSecond() 方法,得到第二个单词(word2)。
  • .equals(...):字符串比较内容是否相同(不能用 == 来比内容)。
  • 如果两个字符串相等,说明这个 pair 是 (word, word) 这种形态,就属于“匹配”。
  • count++:遇到一个匹配的 pair,就把计数加 1。

  • }:结束 for-each 循环。
  • return count;:返回匹配的单词对数量。
  • 最后的 }:结束 numMatches 方法。

  • 重写 toString() 方法:
    • 当你打印一个 WordPairsList 对象时,会自动调用 toString()
  • allPairs.toString()
    • 调用 ArrayListtoString(),会把列表里的所有元素按 [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 类内部访问,符合封装原则。

  • 构造方法:
    • 参数 word1word2 是传进来的两个单词。
  • 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 引用它

    这一行做了两件事:
    1. new WordPair("hi", "there")
        • 调用了下面定义的 WordPair 构造方法,传入两个字符串 "hi""there"
        • 会创建一个 WordPair 对象,其中:
          • word1 = "hi"
          • word2 = "there"
    1. pairs.add( … )
        • addArrayList 的方法,用来把一个元素放到列表的末尾
        • 这里就是:把刚刚创建好的 WordPair("hi", "there") 放进 pairs 这个列表里。

    • 同理,再创建一个 WordPair 对象:
      • word1 = "hi"
      • word2 = "bye"
    • 再把这个对象添加到 pairs 的后面。
    • 此时 pairs 里有两个元素(两个 WordPair 对象):
        1. (hi, there)
        1. (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 类。

    总结一下整体运行流程

    1. 程序从 main 方法开始执行。
    1. 创建一个 ArrayList<WordPair>pairs
    1. pairs 里添加两个 WordPair 对象:
        • "hi", "there"
        • "hi", "bye"
    1. System.out.println(pairs)
        • ArrayList 调用每个 WordPairtoString(),得到:(hi, there)(hi, bye)
        • 然后组合成:[(hi, there), (hi, bye)] 打印出来。

     
    词汇记忆程序CSAWESOME 4.6代码详解
    Loading...