从txt文件中检索一个随机字并且没有输出,并且没有编译器错误java
我无法更改程序的shell,最终目标是从txt文件中的单词列表中选择一个随机单词。 我已经扫描了很多次,逐个浏览代码,尝试了许多不同的东西,但每次运行它,它编译没有问题,但我从来没有得到任何输出。 我甚至尝试在私人function中插入一些输出,但无济于事。 任何人都可以看到我的代码有什么问题或者可以向我解释发生了什么?
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()); } }
构造函数扫描程序(String source)实际上解析源字符串的内容,而不是将其视为文件名,您需要
new Scanner(new File(fileName))
我建议重新考虑你的结构。 你不知道文件中会有多少单词,所以你应该使用Collection
而不是一些固定的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 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()); } }
根据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
与问题无关,但你应该考虑重写这个function:
//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(); }
如果它没有在任何地方使用并且只使用words.length
,你可以完全抛弃getCount
。 当多次调用read
函数时,如果可以在其间添加单词,则应清除集合。 否则,您可以跳过所有元素,直到您已经在线,然后向集合中添加更多元素。
- 您的实例变量random是未初始化的,您将获得NPE。
- 像其他人建议的那样使用新文件(this.filename)。
- 你的getCount方法陷入无限循环,因为你没有调用Scanner.next()。
- 按照其他人的建议使用Collections对象。
- 每次需要计数时,您都不需要遍历整个列表。
- 最小化使用或完全避免使用实例变量是一种很好的做法。
我建议你只需将文件读入一个字符串列表一次。 那么你的count方法就是在你的列表上调用size()。 这是一个可用于读取文件并将其解析为字符串列表的方法:
public List readFile(String filePath) throws IOException { List 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; }