我正在读取一个文本文件,并将该文本文件中的一组唯一单词存储到一个ArrayList中(如果有更好的结构,请建议这样做)。我正在使用扫描程序扫描文本文件并将分隔符指定为“”(空格),如下所示;
ArrayList <String> allWords = new ArrayList <String> ();
ArrayList <String> Vocabulary = new ArrayList <String> ();
int count = 0;
Scanner fileScanner = null;
try {
fileScanner = new Scanner (new File (textFile));
} catch (FileNotFoundException e) {
System.out.println (e.getMessage());
System.exit(1);
}
fileScanner.useDelimiter(" ");
while (fileScanner.hasNext()) {
allWords.add(fileScanner.next().toLowerCase());
count++;
String distinctWord = (fileScanner.next().toLowerCase());
System.out.println (distinctWord.toString());
if (!allWords.contains(distinctWord)) {
Vocabulary.add(distinctWord);
}
}
因此,在打印词汇表的内容后,每个单词后都会跳过一个单词。因此,例如,如果我有以下文本文件;
“快速的棕色狐狸跳过懒狗”
打印的内容是“快速狐狸懒”,然后它给我一个错误;
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at *java filename*.getWords(NaiveBayesTxtClass.java:82)
at *java filename*.main(NaiveBayesTxtClass.java:22)
有人可以就如何解决这个问题给我一些建议吗?我感觉它与fileScanner.useDelimiter和fileScanner.hasNext()语句有关。
答案 0 :(得分:5)
在检查hasNext()一次后,你正在调用Scanner#next()两次,而你忽略了next()的一个返回。
你在(1)调用它并将其添加到allWords
并在(2)再次调用并打印出来。
while (fileScanner.hasNext()) {
allWords.add(fileScanner.next().toLowerCase()); // **** (1)
count++;
String distinctWord = (fileScanner.next().toLowerCase()); // **** (2)
System.out.println (distinctWord.toString());
if (!allWords.contains(distinctWord)) {
Vocabulary.add(distinctWord);
}
}
解决方案:调用Scanner#next() 一次 ,保存返回给变量的String,然后将变量添加到HashSet,并打印变量。如,
while (fileScanner.hasNext()) {
String word = fileScanner.next().toLowerCase();
allWords.add(word); // **** (1)
count++;
// String distinctWord = (fileScanner.next().toLowerCase()); // **** (2)
System.out.println (word);
vocabularySet.add(word); // a HashSet
}
安全的一般规则是,对于Scanner#hasNextXXX()
和Scanner#nextXXX()
的每次通话,您应该建立一对一的关系
答案 1 :(得分:2)
您还要求提供数据结构,您可以这样做:
List<String> allWords = new ArrayList<String>();
SortedSet<String> Vocabulary = new TreeSet<String>();
int count = 0;
Scanner fileScanner = null;
try {
fileScanner = new Scanner(new File(textFile));
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
System.exit(1);
}
fileScanner.useDelimiter(" ");
while (fileScanner.hasNext()) {
String word = fileScanner.next().toLowerCase();
allWords.add(word);
if (Vocabulary.add(word)) {
System.out.print("+ ");
}
System.out.println(word);
}
正如您所看到的,变量由interface(List,SortedSet)声明并使用具体类实现。这不仅允许重新实现,而且对函数参数特别有用。