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

Java 重用一小部分代码的最简单方法,java,methods,formatting,Java,Methods,Formatting,我有这样一段代码: while (scanFile.hasNextLine()) { String currentLine = scanFile.nextLine(); if (currentLine.isEmpty()) { System.out.println(); c

我有这样一段代码:

            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();
}
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);
            }
        }
    }
}
public interface FileHandler {
    public void handle(String[] allWordsInCurrentLine);
}
public class PigLatinFileHandler implements FileHandler {
    public void handle(String[] allWordsInCurrentLine) {
        // Do your piglatin code.
    }
}
public class Base {
  public void run() {
    while(...) {
      consume(word);
    }
  }
  protected void consume(string word){
  }
}
这其中有一些问题,尤其是它看起来很糟糕。有人建议我尝试接口,但它们有点超出我的地位(我才上了几周的课)。有人有其他建议吗


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

我会将三个不同进程所需的功能包装在它们自己的自定义可调用类中,然后将它们传递给上面的代码。在这种情况下,共享代码看起来类似于s:

for(String currentWordInCurrentLine : allWordsInCurrentLine)
{
    if (i==0)
        pigLatin(currentWordInCurrentLine);         // Part 1
    if (i==1)
        searchForWord(currentWordInCurrentLine, currentLine);   // Part 2
    if (i==2)
        brailleTranslator();
}
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);
            }
        }
    }
}
public interface FileHandler {
    public void handle(String[] allWordsInCurrentLine);
}
public class PigLatinFileHandler implements FileHandler {
    public void handle(String[] allWordsInCurrentLine) {
        // Do your piglatin code.
    }
}
public class Base {
  public void run() {
    while(...) {
      consume(word);
    }
  }
  protected void consume(string word){
  }
}
您的第一个可能如下所示:

for(String currentWordInCurrentLine : allWordsInCurrentLine)
{
    if (i==0)
        pigLatin(currentWordInCurrentLine);         // Part 1
    if (i==1)
        searchForWord(currentWordInCurrentLine, currentLine);   // Part 2
    if (i==2)
        brailleTranslator();
}
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);
            }
        }
    }
}
public interface FileHandler {
    public void handle(String[] allWordsInCurrentLine);
}
public class PigLatinFileHandler implements FileHandler {
    public void handle(String[] allWordsInCurrentLine) {
        // Do your piglatin code.
    }
}
public class Base {
  public void run() {
    while(...) {
      consume(word);
    }
  }
  protected void consume(string word){
  }
}
最后,要运行它,您可以执行以下操作

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.
}
publicstaticvoidmain(字符串[]args){
IndexingFileHandler indexHandler=新的IndexingFileHandler();
列表处理程序=新建LinkedList();
add(新的PigLatinFileHandler());
add(indexHandler);
add(新的similarTopiglationFileHandler());
processFile(文件,处理程序);
//注意,现在您有一个对indexHandler的引用;因此如果您想保存
//处理单词时的任何状态都可以,并在此处使用它。
}
编辑

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


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

一种可能性是将您的逻辑放入如下基类:

for(String currentWordInCurrentLine : allWordsInCurrentLine)
{
    if (i==0)
        pigLatin(currentWordInCurrentLine);         // Part 1
    if (i==1)
        searchForWord(currentWordInCurrentLine, currentLine);   // Part 2
    if (i==2)
        brailleTranslator();
}
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);
            }
        }
    }
}
public interface FileHandler {
    public void handle(String[] allWordsInCurrentLine);
}
public class PigLatinFileHandler implements FileHandler {
    public void handle(String[] allWordsInCurrentLine) {
        // Do your piglatin code.
    }
}
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的解决方案就是最好的选择。

我会试试看——乍一看,看起来很棒。你解释得很好,谢谢。我能问一下——我需要创建IndexingFileHandler和FileHandlerManager吗对象?我在Java中遇到错误,说它们无法解析为类型。@AndrewMartin是的,我为它们提供了基本的类定义;它们应该是非常轻量级的。如果您担心类文件爆炸并使代码更难理解,您也可以在FileHandlerManager:或change
FileHandlerMa中创建它们的内部类nager
FileHandler
并使processFile保持其唯一的静态方法。谢谢,我们将查看您和他的答案,看看哪一个最适合!