Java读取EnglishWords.txt无单词被检查问题及优化咨询
问题描述
我并非资深Java开发者,正在完成斯坦福大学Nifty拼字Bee作业,需求是读取EnglishWords.txt文件(文件内单词每行一个,示例内容如下):
a aa aah aahed aahing aahs aal aalii aaliis aals aardvark aardvarks aardwolf aardwolves aargh aas aasvogel aasvogels aba abaca abacas abaci aback abacus abacuses abaft
我编写的solveAction()方法用于按钮点击事件,逻辑正常,但调用readWordsFromFile()方法后,出现无单词被检查的情况。相关代码如下:
核心业务代码
private void solveAction() throws IOException { String puzzle = sbg.getBeehiveLetters(); // Read words from the file ArrayList<String> wordList = readWordsFromFile(ENGLISH_DICTIONARY); // ENGLISH_DICTIONARY是定义为EnglishWords.txt的final字符串 // Find all valid words using the checkValidWord function ArrayList<String> validWords = new ArrayList<>(); for (String word : wordList) { if (checkValidWord(word, puzzle)) { validWords.add(word); } } if (validWords.isEmpty()) { sbg.showMessage("No valid words found", Color.BLACK); } else { sbg.showMessage("Found words:", Color.BLACK); for (String word : validWords) { sbg.addWord(word, Color.BLUE); } // showMessage和addWord已在其他类中实现 } } // Check if a word is valid based on the puzzle private boolean checkValidWord(String word, String puzzle) { // Check word length if (word.length() < 4) { return false; } // Check for only puzzle letters for (char c : word.toCharArray()) { if (!puzzle.contains(String.valueOf(c))) { return false; } } // Check for center letter at the start if (word.charAt(0) != puzzle.charAt(0)) { return false; } // All checks passed, word is valid return true; }
文件读取代码
public ArrayList<String> readWordsFromFile(String filename) throws IOException { ArrayList<String> words = new ArrayList<>(); try (BufferedReader reader = new BufferedReader(new FileReader(filename))) { String line; while ((line = reader.readLine()) != null) { // Clean and filter the line (optional) line = line.trim().toLowerCase(); // Remove whitespace and convert to lowercase // Add the word only if it has valid characters and length if (isValidWord(line)) { words.add(line); } } } return words; } // Check if a word is valid based on your criteria private boolean isValidWord(String word) { // You can define your own criteria for a valid word here // For example, check for minimum length, only alphabetic characters, etc. return word.matches("[a-z]+") && word.length() >= 4; }
请问是否存在更简便的文件读取方式?或是我的代码中存在错误导致无单词被检查?
问题解决与优化建议
一、代码错误排查
- 核心规则错误:
checkValidWord中要求单词首字符必须等于puzzle的首字符,这不符合拼字Bee的规则——规则是单词必须包含中心字母(即puzzle的首字符),而非首字符必须是中心字母。这会直接过滤掉所有首字母不是中心字母但包含中心字母的有效单词,是导致无结果的主要原因。修正逻辑:// 替换原首字符检查逻辑 if (!word.contains(String.valueOf(puzzle.charAt(0)))) { return false; } - 大小写不匹配:
readWordsFromFile将单词转为小写,但如果sbg.getBeehiveLetters()返回的是大写字母,会导致puzzle.contains(String.valueOf(c))匹配失败。需统一大小写:// 在solveAction中先将puzzle转为小写 String puzzle = sbg.getBeehiveLetters().toLowerCase(); - 文件路径验证:确认
ENGLISH_DICTIONARY的路径是否正确,比如是否在项目根目录、是否包含完整路径。可以在readWordsFromFile末尾添加打印语句验证读取数量:System.out.println("读取到的单词总数:" + words.size()); - 过滤逻辑验证:
isValidWord要求单词长度≥4,会过滤掉示例中所有短单词,这符合拼字Bee规则(单词长度至少4),但需确保字典中存在符合长度要求的单词。
二、更简便的文件读取方式
使用Java 8+的Files类结合Stream API,可大幅简化文件读取代码,代码更简洁易读:
import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.stream.Collectors; public ArrayList<String> readWordsFromFile(String filename) throws IOException { return Files.lines(Paths.get(filename)) .map(String::trim) .map(String::toLowerCase) .filter(this::isValidWord) .collect(Collectors.toCollection(ArrayList::new)); }
该方式自动处理资源关闭,通过链式调用完成修剪、转小写、过滤和收集操作,无需手动写循环和缓冲区。
内容的提问来源于stack exchange,提问作者Kareem Gabareen Mokhtar
相关产品推荐
相关产品推荐

