2

我有一段这样的代码:

            while (scanFile.hasNextLine()) 
            {
                String currentLine = scanFile.nextLine();
                if (currentLine.isEmpty())
                {
                    System.out.println();
                    continue;
                }
                String[] allWordsInCurrentLine = currentLine.split(" ");    

然后,我想使用三种不同的方法来操作正在扫描的文件。

第一种方法单独扫描代码的每一行并逐行打印出某种形式的输出(pigLatin)(因此“while”循环的每次迭代都会给出一行输出。
第二种方法首先扫描所有文本,然后将各种信息存储在不同的数组和变量中。然后用户可以搜索这些信息(因此在给出任何输出之前必须满足整个“while”循环)。然后我有第三种方法,它与第一种方法类似。

我试图找到重用这部分代码的最有效方法。最初,我尝试只在上面代码的底行下方进行方法调用,并在其顶部有一个 for 循环,所以如果 a==0,调用第一个方法,然后通过 while 循环第二次,a 将递增并且将调用第二种方法,依此类推,如下所示:

for(String currentWordInCurrentLine : allWordsInCurrentLine)
{
    if (i==0)
        pigLatin(currentWordInCurrentLine);         // Part 1
    if (i==1)
        searchForWord(currentWordInCurrentLine, currentLine);   // Part 2
    if (i==2)
        brailleTranslator();
}

这有一些问题,尤其是它看起来很糟糕的事实。有人建议我尝试接口,但它们比我的位置高一点(我的课程只有几周时间)。有没有人有任何其他建议?

编辑: pigLatin 方法调用使用上述(尽管看起来很可怕)方式可以正常工作。但是,我不能这样调用下一个方法,因为它需要运行整个“while”循环才能运行。

4

2 回答 2

2

我会将您想要的功能与您的三个不同进程包装在他们自己的自定义可调用类中,然后将它们传递给上面的代码。在这种情况下,共享代码将如下所示:

public class FileHandlerManager {

    public static void processFile(File file, List<FileHandler> handlers) {

        // ... Setup your scanFile from your file... leaving this out.

        while (scanFile.hasNextLine()) {

            String currentLine = scanFile.nextLine();

            String[] allWordsInCurrentLine = currentLine.split(" ");

            for (FileHandler handler : handlers) {
                handler.handle(allWordsInCurrentLine);
            }
        }
    }
}

然后,您可以共享该 while 循环的功能FileHandler。什么是FileHandler? 我会很简单地定义它,如下所示:

public interface FileHandler {
    public void handle(String[] allWordsInCurrentLine);
}

您的第一个可能如下所示:

public class PigLatinFileHandler implements FileHandler {
    public void handle(String[] allWordsInCurrentLine) {
        // Do your piglatin code.
    }
}

最后,要运行它,你会做这样的事情

public static void main(String[] args) {

    IndexingFileHandler indexHandler = new IndexingFileHandler();

    List<FileHandler> handlers = new LinkedList<FileHandler>();
    handlers.add(new PigLatinFileHandler());
    handlers.add(indexHandler);
    handlers.add(new SimilarToPigLatinFileHandler());

    FileHandlerManager.processFile(file, handlers);

    // Note now you have a reference to indexHandler; so if you wanted to save
    // any state while processing the words you can, and use it here.
}

编辑

我只想指出,有一种“更简单”、更少面向对象的方式;您可以有一个方法获取一个文件并返回一个 String[][],它是文件行的二维数组,按这些行中的单词排列。然后您可以将该数组传递给您的处理程序。

然而,这种方法的缺点是它会破坏大文件(您必须一次将整个内容加载到内存中)并且在读取整个文件之前您不会得到任何输出。我的回答的一个(也许不是显而易见的)优势是您“流式传输”文件;您使用所有处理程序处理一行,然后丢弃该行,允许 java 重用该内存。这段代码可以让你处理一个 10 GB 的文件,同时只使用等于该文件中最长行长度的 java 内存(加上 IndexHandler 正在保存的任何状态)。

于 2012-11-26T22:19:45.647 回答
0

一种可能性是将您的逻辑放入这样的基类中:

public class Base {
  public void run() {
    while(...) {
      consume(word);
    }
  }
  protected void consume(string word){
  }
}

然后您可以为每个作业创建一个类:

public PigLatin extends Base {
  protected void consume(string word) {
    // do piggy stuff..
  }
}

您可以像这样运行所有内容:

...
Base l1 = new PigLatin();
l1.run();

Base l2 = new WordSearch();
l2.run();
...

在您的情况下,这样做看起来不合理,它可能会使您的代码复杂化。但我认为这是一个很好的锻炼。

The disadvantage of this solution is that you have to iterate through your file every time you call run(). You usually do this if you want to separate different runs. If you're sure those runs don't interfere with each other, then Cory Kendall's solution is the way to go.

于 2012-11-26T22:30:32.643 回答