2012-06-03 37 views
2

我正在读取一个文本文件,并将该文本文件中的一组唯一字存储到一个ArrayList中(请确认是否有更好的结构来完成此操作)。我使用扫描仪扫描文本文件并将分隔符指定为“”(空格),如下所示;Java分隔符跳过一个词

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()语句有关。

+2

使用['HashSet'](http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html)而不是'ArrayList' - 它会自动忽略重复项。 –

+0

Thankyou Greg,使用HashSet更容易,工作也更少。非常感激。 – Triple777er

回答

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); 

    } 
} 

解决方案:调用扫描仪#next()的一次,保存字符串返回给一个变量,然后将变量添加到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()

+0

谢谢非常先生,这解决了我的问题。 – Triple777er

+0

@ Triple777er:不客气! –

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); 
    } 

正如你所看到的变量的接口(列表,SortedSet的)声明,并用具体的类实现。这不仅允许重新实现,而且对于函数参数特别有用。

相关问题