我目前正忙于一所小型大学的作业,并且对我实现的字典类的contains()方法有一些麻烦-该方法始终返回false。该类如下所示:
public class LocalDictionary {
private ArrayList<String> wordsSet;
public LocalDictionary() throws IOException {
String wordListContents = new String(Files.readAllBytes(Paths.get("words.txt")));
wordsSet = new ArrayList<>();
String[] words = wordListContents.split("\n");
for (int i = 0; i < words.length; i++) {
wordsSet.add(words[i].toLowerCase());
}
}
public boolean contains(String word) {
return wordsSet.contains(word.toLowerCase());
}
}
可从https://raw.githubusercontent.com/dwyl/english-words/master/words_alpha.txt获得字典用来获取单词的“ words.txt”文件,但这是其外观的摘要:
zinked
zinkenite
zinky
zinkiferous
zinkify
zinkified
zinkifies
zinkifying
zinnia
zinnias
zinnwaldite
zinober
zinsang
zinzar
zinziberaceae
我确保“ words.txt”中包含的单词包含在“ wordsSet”中,但无法弄清楚为什么contains方法对出现在ArrayList中的单词返回false。
非常感谢您的帮助。
答案 0 :(得分:0)
在添加前修剪for循环中的每一行。该行中每个单词后面似乎都有一些多余的空间。
for (int i = 0; i < words.length; i++) {
wordsSet.add(words[i].toLowerCase());
}
到
for (int i = 0; i < words.length; i++) {
wordsSet.add(words[i].trim().toLowerCase());
}
可以使用wordsSet.get(1).length()
进行验证。根据您的文件,第一行是'aa',但是它打印的是3而不是2,这是因为每个单词后面都有一个多余的空格,需要在添加到列表之前进行修剪。
您的contains()
方法没有问题。
答案 1 :(得分:0)
尝试使用BufferedReader
,我为我努力工作(我删除了一些没用的行)。在您使用时,您正在从文件读取所有字节,将有多余的字节。
public class LocalDictionary {
private ArrayList<String> wordsSet = new ArrayList<>();
public LocalDictionary() throws Exception {
//dont forget to absolute path to here. click righ click to file and copy path
File file = new File("C:\\Users\\higuys\\IdeaProjects\\try\\src\\words.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null)
//trim and tolowercase and add to list.
wordsSet.add(line.trim().toLowerCase());
}
public boolean contains(String word) {
return wordsSet.contains(word.toLowerCase());
}
}
答案 2 :(得分:0)
您的问题似乎是操作系统依赖的行分离器的错误处理,在这里
String[] words = wordListContents.split("\n");
在字典的字符串上保留多余的字符。并非所有操作系统都使用“ \ n”来分隔行,因此您应该编写代码以考虑到这一点。
一种选择是让Java告诉您要使用的行分隔符,然后使用它:
String lineSeparator = System.getProperty("line.separator");
String[] words = wordListContents.split(lineSeparator);
在我看来,最简单的方法是使用“文件”获取所有行,例如:
private List<String> wordsSet1;
private ArrayList<String> wordsSet2;
public TestDictionary(String path) throws IOException {
// my code:
wordsSet1 = Files.readAllLines(Paths.get(path));
通过使用文件readAllLines,您可以让Java选择正确的行分隔符。
将您的代码与我的代码进行比较:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import save.MyColorFoo;
public class TestDictionary {
// public static final String TXT_PATH = "src/pkg1/words.txt";
// TODO: change this to your correct path
public static final String TXT_PATH = "words.txt";
private List<String> wordsSet1;
private ArrayList<String> wordsSet2;
public TestDictionary(String path) throws IOException {
// my code:
wordsSet1 = Files.readAllLines(Paths.get(path));
// his code
String wordListContents = new String(Files.readAllBytes(Paths.get(path)));
wordsSet2 = new ArrayList<>();
String[] words = wordListContents.split("\n");
for (int i = 0; i < words.length; i++) {
wordsSet2.add(words[i].toLowerCase());
}
}
public boolean myContains(String word) {
return wordsSet1.contains(word.toLowerCase());
}
public boolean hisContains(String word) {
return wordsSet2.contains(word.toLowerCase());
}
public static void main(String[] args) {
try {
TestDictionary testDictionary = new TestDictionary(TXT_PATH);
String testWord = "zinky";
System.out.println("My List contains \"zinky\": " + testDictionary.myContains(testWord));
System.out.println("His List contains \"zinky\": " + testDictionary.hisContains(testWord));
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果不确定原始文本文件是否包含所有小写字母,然后需要降低它们,则可以使用Streams来帮助您完成此操作:
wordsSet1 = Files.readAllLines(Paths.get(path))
.stream().map(s -> s.toLowerCase())
.collect(Collectors.toList());