2014-02-07 4 views
0

Я не могу изменить оболочку программы, конечной целью является выбор случайного слова из списка слов в txt-файле. я просканировал это много раз, прошел код один за другим, пробовал много разных вещей, но каждый раз, когда я его запускаю, он компилируется без проблем, но я никогда не получаю никакого вывода. я даже пытался вставить некоторый вывод в частные функции, но безрезультатно. может ли кто-нибудь увидеть, что не так с моим кодом, или может объяснить мне, что происходит?Извлечение случайного слова из txt-файла и получение результата без ошибок компилятора java

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()); 
     } 
    } 
+0

Вы когда-нибудь называли функцию 'read'? –

+0

this.read() в конструкторе – amudhan3093

+0

Ах да, я вижу, и 'getCount' возвращает что? –

ответ

1

Constructor Сканер (источник String) на самом деле анализировать содержимое исходной строки, вместо того, чтобы рассматривать его как имя файла, Вам нужно

new Scanner(new File(fileName)) 
1

Согласно документации Oracle, вы должны использовать new File в качестве аргумента для сканера.

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

Unrelated на вопрос, но вы должны действительно думать о перезаписи этой функции:

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

Когда вы читаете файл один раз, чтобы получить все слова, следует обновить 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 вы должны очистить коллекцию, если между словами можно добавить слова. В противном случае вы можете пропустить все элементы до тех пор, пока строка, на которой вы уже были, а затем добавьте в коллекцию больше элементов.

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()); 
    } 
} 
0
  1. Ваш экземпляр переменной случайным является неинициализированным, вы получите NPE.
  2. Используйте новый файл (this.filename), как предложили другие люди.
  3. Ваш метод getCount застревает в бесконечном цикле, потому что вы не вызывали Scanner.next().
  4. Используйте объект Collections, как это было предложено другими.
  5. Вам не нужно перебирать весь список каждый раз, когда вам нужно получить счет.
  6. Это хорошая практика для минимизации использования или полного исключения переменных экземпляра.
0

Я бы предложил прочитать ваш файл в списке строк только один раз. то ваш метод подсчета просто вызовет 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; 
}