重用小部分代码的最简单方法

时间:2012-11-26 21:56:00

标签: java methods formatting

我有一段这样的代码:

            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'循环。

2 个答案:

答案 0 :(得分:2)

我会将你想要的功能与你自己的三个不同进程包装在他们自己的自定义类似callable中,然后将它们传递给上面的代码。在这种情况下,共享代码看起来像这样:

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

然后,您可以在FileHandler之间共享while循环的功能。什么是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正在保存的任何状态)。

答案 1 :(得分: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();
...

在您的情况下,执行此操作看起来不合理,可能会使您的代码复杂化。但我认为这是一个很好的练习。

此解决方案的缺点是每次调用run()时都必须遍历文件。如果要分隔不同的运行,通常会执行此操作。如果您确定这些运行不会相互干扰,那么Cory Kendall的解决方案就是您的选择。