2

我正在尝试使用 JDK 8 用 Ja​​va 编写一个 Concordance 程序(以重新学习该语言)。到目前为止,我有以下内容(省略了包名):

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static Map<String,Integer> generateConcordance(String fileName) throws IOException {
        Map<String,Integer> concordance = new HashMap<>();

        for (String line : Files.readAllLines(Paths.get(fileName))) {
            for (String word : line.split("[\\p{Punct}\\s]+")) {
                concordance.merge(word, 1, Integer::sum);
            }
        }

        return concordance;
    }

    public static void main(String[] args) {
        if (args.length == 0) {
            System.err.println("invalid operation - you must specify an input file");
        } else {
            try {
                Map<String, Integer> concordance = generateConcordance(args[0]);
                concordance.forEach((key,value) -> System.out.println(key + "\t" + value));
            } catch (IOException error) {
                System.err.println("I/O error - unable to read the file: " + args[0]);
            }
        }

    }

}

这可行,但我想概括实现,以便能够在System.in没有传递参数的情况下读取输入。是否可以修改函数的输入以generateConcordance允许将其应用于命名文件或System.in

4

1 回答 1

1

通过一些重构,使用Stream<String>它应该非常简单。您可以尝试以下(未经测试):

public class Main {

  private static final Pattern wordBreak = Pattern.compile("[\\p{Punct}\\s]+");

  public static Map<String, Long> generateConcordance(Stream<String> lines) {
    return lines
      .flatMap(wordBreak::splitAsStream)
      .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
  }

  public static Map<String, Long> generateConcordance(String fileName) throws IOException {
    try (Stream<String> lines = Files.lines(Paths.get(fileName))) {
      return generateConcordance(lines);
    }
  }

  public static Map<String, Long> generateConcordance(InputStream in) {
    InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
    return generateConcordance(new BufferedReader(reader).lines());
  }

  public static void main(String[] args) {
    try
    {
      generateConcordance("SomeRandomFile.txt");
      generateConcordance(System.in);
    }
    catch (IOException e)
    {
      e.printStackTrace(System.err);
    }
  }
}
于 2015-06-02T03:44:21.710 回答