从txt文件中检索一个随机单词并且没有输出,并且没有编译器错误java

时间:2014-02-07 05:27:55

标签: java drjava

我无法更改程序的shell,最终目标是从txt文件中的单词列表中选择一个随机单词。我已经扫描了很多次,逐个浏览代码,尝试了许多不同的东西,但每次运行它,它编译没有问题,但我从来没有得到任何输出。我甚至尝试在私人功能中插入一些输出,但无济于事。任何人都可以看到我的代码有什么问题或者可以向我解释发生了什么?

import java.util.*;

    class PartOfSpeech
    {
      private String[] words;
      private Random random;
      private String filename;

      public PartOfSpeech(String filename)
      {
        this.filename = filename;
        this.read();
      }
      //this picks a random number and uses that number for the index of the array for which to return
      public String getRandomWord()
      {
        int index;
        index = random.nextInt(this.getCount());
        return words[index];
      }
      //this gets a count of how many lines of txt are in the file
      private int getCount()
      {
        Scanner fr = new Scanner(this.filename);
        int count = 0;
        while(fr.hasNextLine())
        {
         count++;
        }
       return count; 
      }
      //this creates a scanner and inserts each word from the txt file into an array
      private void read()
      {
        Scanner fr = new Scanner(this.filename);
        for(int i=0; i<this.getCount(); i++)
        {
         words[i] = fr.nextLine(); 
        }
      }

      public static void main(String[] args)
      {
        PartOfSpeech n = new PartOfSpeech("nouns.txt");
        System.out.print(n.getRandomWord());
      }
    }

5 个答案:

答案 0 :(得分:1)

构造函数扫描程序(字符串源代码)实际解析源字符串的内容,而不是将其视为文件名,您需要

new Scanner(new File(fileName))

答案 1 :(得分:1)

根据Oracle文档,您应该使用new File作为Scanner的参数。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html

  private void read()
  {
    Scanner fr = new Scanner(new File(this.filename));
    for(int i=0; i<this.getCount(); i++)
    {
     words[i] = fr.nextLine(); 
    }
  }

与此问题无关,但您应该考虑重写此功能:

  //this gets a count of how many lines of txt are in the file
  private int getCount()
  {
    Scanner fr = new Scanner(this.filename);
    int count = 0;
    while(fr.hasNextLine())
    {
     count++;
    }
   return count; 
  }

当您读取文件一次以获取所有单词时,您应该更新那里的计数值,而不是在getCount中多次重新打开文件。如果文件发生变化,count将与words内的项目数量不同。

我使用ArrayList而不是[]:

将代码重构为类似的东西
  private void read()
  {
    Scanner fr = new Scanner(new File(this.filename));

    // reloading the file should clear the collection first
    words.clear()

    while(fr.hasNextLine())
    {
     words.add(fr.nextLine()); 
    }
  }

  private int getCount()
  {
   return words.size(); 
  }

如果它没有在任何地方使用过,你可能完全放弃getCount,只能使用words.length。当多次调用read函数时,如果可以在其间添加单词,则应清除集合。否则,您可以跳过所有元素,直到您已经在线,然后向集合中添加更多元素。

答案 2 :(得分:1)

我建议重新考虑你的结构。你不知道文件中会有多少单词,所以你可能应该使用Collection<String>而不是一些固定的String[],以避免迭代多次。也许你可以尝试类似的东西:

import java.io.File;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class PartsOfSpeech {

    private final List<String> words;
    private final File file;

    private int index;

    public PartsOfSpeech(final String filePath){
        words = new LinkedList<>();

        file = new File(filePath);
        read();

        Collections.shuffle(words);
    }

    private void read(){
        try{
            final Scanner input = new Scanner(file, "UTF-8");
            while(input.hasNextLine())
                words.add(input.nextLine());
            input.close();
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

    public String getRandomWord(){
        if(index == words.size()){
            index = 0;
            Collections.shuffle(words);
        }
        return words.isEmpty() ? null : words.get(index++);
    }

    public static void main(String[] args){
        final PartsOfSpeech pos = new PartsOfSpeech("noun.txt");
        System.out.println(pos.getRandomWord());
    }
}

答案 3 :(得分:0)

  1. 您的实例变量random是未初始化的,您将获得NPE。
  2. 像其他人建议的那样使用新文件(this.filename)。
  3. 你的getCount方法陷入无限循环,因为你没有调用Scanner.next()。
  4. 按照他人的建议使用Collections对象。
  5. 每次需要计算时,您都不需要遍历整个列表。
  6. 最好尽量减少使用或完全避免使用实例变量。

答案 4 :(得分:0)

我建议您只将文件读入一个字符串列表一次。那么你的count方法就是在你的列表上调用size()。这是一个可用于读取文件并将其解析为字符串列表的方法:

    public List<String> readFile(String filePath) throws IOException {
    List<String> result = new ArrayList<>();
    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(
                    new FileInputStream(filePath)))) {
        String line;
        while ((line = reader.readLine()) != null) {
            result.add(line.replace("\n", ""));
        }
    }

    return result;
}