I'm attempting to write a Concordance program in Java using JDK 8 (to relearn the language). So far, I have the following (package name omitted):
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]);
}
}
}
}
This works, but I'd like to generalize the implementation to be able to read input from System.in
if no arguments are passed. Is it possible to modify the input to the function generateConcordance
to allow it to be applied to either a named file or System.in
?
With a little bit of refactoring, and using Stream<String>
this should be pretty straightforward. You could try the following (untested):
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);
}
}
}