今天带大家从零实现背单词软件V1.0,涵盖文件数据读取、随机抽题、字符串处理等核心知识点,代码注释超详细,一看就会!
一、项目核心功能(对标文档需求)
(1) 读取本地单词文件(支持CET4/CET6词库)
(2) 随机抽取单词并隐藏一个字母
(3)接收用户输入,判断答案对错并反馈
(4)循环出题,直到手动退出
二、必备知识点预热(新手必看)
在写代码前,先搞懂这几个关键技术点:
- ArrayList集合:存储单词和对应的中文翻译,比数组更灵活(支持动态添加元素)
- 文件IO流:用FileReader+BufferedReader读取本地txt文件,实现"词库外置"
- Random类:生成随机数,用于随机选单词、随机隐藏字母
- String类方法:substring(截取字符串)、split(拆分字符串)、charAt(获取指定位置字符)
- Scanner类:接收用户控制台输入
三、完整代码实现(逐行注释)
(1)准备词库文件
1. 在项目根目录创建 wordslib 文件夹

2. 新建 CET4.txt 和 CET6.txt,按"英文#中文"格式写单词(示例):

(2)完整代码展示
java
// 导入所需工具类(新手记住:用到什么导什么)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class WordsDemo {
public static void main(String[] args) {
// 1. 创建工具类对象
Scanner sc = new Scanner(System.in); // 接收用户输入
Random ran = new Random(); // 生成随机数
ArrayList<String> words = new ArrayList<>(); // 存英文单词
ArrayList<String> chineseWords = new ArrayList<>(); // 存中文翻译
String wordsLib = ""; // 存储词库文件路径
// 2. 让用户选择词库
System.out.println("请选择对应的单词表编号:");
System.out.println("=====1001-CET4=====");
System.out.println("=====1002-CET6=====");
int num = sc.nextInt(); // 读取用户选择的编号
// 3. 根据选择确定词库路径
if (num == 1001) {
wordsLib = "wordslib/CET4.txt";
} else if (num == 1002) {
wordsLib = "wordslib/CET6.txt";
} else {
System.out.println("编号错误!默认使用CET4词库~");
wordsLib = "wordslib/CET4.txt";
}
// 4. 读取词库文件(核心:文件IO流操作)
File file = new File(wordsLib); // 创建文件对象,关联词库文件
try {
// FileReader:读取文件字符流;BufferedReader:缓冲流,提高读取效率
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line; // 存储每次读取的一行数据
// 循环读取每一行,直到文件末尾(line为null时结束)
while ((line = br.readLine()) != null) {
// 按"#"拆分字符串,得到英文和中文(比如"hello#你好"拆成["hello","你好"])
String[] strs = line.split("#");
String eng = strs[0]; // 英文单词
String chinese = strs[1]; // 中文翻译
words.add(eng); // 加入英文集合
chineseWords.add(chinese); // 加入中文集合
}
br.close(); // 关闭缓冲流
fr.close(); // 关闭文件流
} catch (FileNotFoundException e) {
// 捕获"文件找不到"异常(比如路径写错、文件删除了)
throw new RuntimeException("词库文件找不到!请检查路径是否正确", e);
} catch (IOException e) {
// 捕获文件读取异常(比如文件损坏)
throw new RuntimeException("文件读取失败!", e);
}
// 5. 循环出题(核心:随机抽题+字符串处理)
int len = words.size(); // 获取单词总数
while (true) { // 外层循环:一直出题,直到手动停止
// 生成随机索引,从集合中选一个单词(0到len-1,避免数组越界)
int index = ran.nextInt(len);
String word = words.get(index); // 获取选中的英文单词
String chinese = chineseWords.get(index); // 对应的中文翻译
// 生成随机位置,隐藏该位置的字母(0到单词长度-1)
int charIndex = ran.nextInt(word.length());
char ch = word.charAt(charIndex); // 记录被隐藏的字母
// 构建带下划线的单词(比如"hello"隐藏第2个字母变成"he_lo")
// substring(0, charIndex):截取从开头到隐藏位置前的字符
// substring(charIndex + 1):截取从隐藏位置后到结尾的字符
String newWord = word.substring(0, charIndex) + "_" + word.substring(charIndex + 1);
// 内层循环:直到用户猜对才换下一题
while (true) {
System.out.println("\n请猜出该单词缺失的字母: " + newWord);
String nch = sc.next(); // 读取用户输入的字母
char newCh = nch.charAt(0); // 转成字符(用户输入单个字母)
// 判断答案是否正确
if (newCh == ch) {
System.out.println("正确~! 完整单词:" + word + " 中文释义:" + chinese);
break; // 猜对了,跳出内层循环,换下一题
} else {
System.out.println("错误!请重新输入!");
}
}
}
}
}
四、关键知识点详解(对应代码)
1. 集合与数组的区别
- 代码中用ArrayList而不是数组,因为数组长度固定,而ArrayList可以动态添加元素(读取多少单词就存多少)
- 常用方法:add(元素)添加数据、get(索引)获取数据、size()获取元素个数
2. 文件读取为什么用两个流?
- **FileReader:**基础文件读取流,只能逐个字符读,效率低
- **BufferedReader:**缓冲流,先把文件数据读到缓冲区,再批量处理,效率高
- **注意:**流使用后必须关闭(close()),否则会占用系统资源
3. 字符串处理核心方法
- split("#"):按指定字符拆分字符串,返回字符串数组(比如处理"英文#中文"格式)
- substring(start, end):截取字符串,包含start索引,不包含end索引(比如"hello".substring(0,2)得到"he")
- charAt(index):获取字符串指定索引位置的字符(索引从0开始,比如"hello".charAt(1)得到'e')
4. 随机数生成注意事项
- ran.nextInt(len):生成0到len-1的随机数,刚好对应ArrayList的索引范围,避免"数组越界"错误
- 随机数用于两个地方:随机选单词、随机隐藏字母,让出题更灵活
五、运行效果展示

六、常见问题与解决方法
(1)运行时报 FileNotFoundException(文件找不到)
原因:
词库文件路径写错、文件没放在指定位置,或文件夹名称拼写错误(比如把 wordslib 写成 wordlib)。
解决:
- 确认项目根目录下有 wordslib 文件夹,且里面有 CET4.txt/CET6.txt;
- 检查代码中路径字符串 wordslib/CET4.txt 的拼写,和文件夹、文件名完全一致;
- 如果是 IDEA/Eclipse 等工具,可右键文件选择 Copy Path 直接复制绝对路径替换(比如 D:/project/wordslib/CET4.txt)。

(2)读取文件后中文翻译乱码
原因:
文件编码格式和程序读取编码不匹配(默认 FileReader 用系统编码,而 txt 文件可能是 UTF-8 编码)。
解决:
把FileReader 换成 InputStreamReader 并指定编码,同时将txt文件的编码设置为UTF-8,代码修改如下:
java
// 替换原来的 FileReader fr = new FileReader(file);
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
BufferedReader br = new BufferedReader(isr);
(3)程序一直循环出题,无法退出
原因:
外层 **while(true)**是死循环,没有退出条件。
解决:
添加退出逻辑,比如输入exit时结束程序,代码修改如下:
java
// 在内层循环读取输入的位置修改
String nch = sc.next();
// 新增:输入exit则退出整个程序
if (nch.equalsIgnoreCase("exit")) {
System.out.println("退出背单词,下次加油!");
sc.close();
System.exit(0); // 终止程序
}
if (nch.length() != 1) {
System.out.println("请输入单个字母!");
continue;
}
(4)单词长度为1时,隐藏后只剩下划线,用户体验感较差
原因:
比如单词 a ,隐藏后变成 _ ,用户不知道该填什么。
解决:
代码中增加单词长度判断,跳过长度为1的单词,代码修改如下:
java
while (true) {
int index = ran.nextInt(len);
String word = words.get(index);
// 跳过长度小于2的单词
if (word.length() < 2) {
continue;
}
String chinese = chineseWords.get(index);
// 后续代码不变...
}
(5)用户输入多个字符时,程序报错 StringIndexOutOfBoundsException
原因:
代码中用 nch.charAt(0) 获取输入字符,如果用户输入多个字符(比如 ab),不会报错,但如果输入空字符串会崩溃;更合理的做法是限制用户只能输入单个字符。
解决:
增加输入长度校验,代码修改如下:
java
String nch = sc.next();
// 校验输入是否为单个字符
if (nch.length() != 1) {
System.out.println("请输入单个字母!");
continue;
}
char newCh = nch.charAt(0);
七、下节版本预告
以上是单词软件V1.0的基础功能展示,覆盖了Java必学的核心知识点:集合、文件IO、字符串处理、异常捕获。下一篇我们会升级到V2.0,即创建窗体,添加给出中文翻译输入单词等功能。新手可以跟着代码逐行敲,遇到不懂的地方对照"知识点详解",跑通后再尝试升级功能。如果现在运行代码遇到问题(比如文件找不到、中文乱码),或者想提前了解V2.0的核心知识点,随时留言告诉我!