I like new Java8 StreamAPI and want use it not only for one file. As usually, I use this code:
Stream<String> lines = Files.lines(Paths.get("/somepathtofile"));
But how read two file in one stream if it possibly?
Without any extra helper functions or outside libraries, the easiest is:
Stream<String> lines1 = Files.lines(Paths.get("/somepathtofile"));
Stream<String> lines2 = Files.lines(Paths.get("/somepathtoanotherfile"));
Stream.concat(lines1, lines)
.filter(...)
.forEach(...);
If Files.lines
hadn't been declared to throw a checked exception, you'd be able to do
Stream.of("/file1", "/file2")
.map(Paths::get)
.flatMap(Files::lines)....
But, alas, we can't do that. There are several workarounds. One is to make your own version of Files.lines
that calls the standard one, catches IOException
and rethrows as an UncheckedIOException
. Another approach is a more general way to make functions out of methods that throw checked exceptions. It would look something like this:
@FunctionalInterface
public interface ThrowingFunction<T,R> extends Function<T,R> {
@Override
public default R apply(T t) {
try {
return throwingApply(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static<T,R> Function<T,R> wrap(ThrowingFunction<T,R> f) {
return f;
}
R throwingApply(T t) throws Exception;
}
and then
Stream.of("/somefile", "/someotherfile", "/yetanotherfile")
.map(Paths::get)
.flatMap(ThrowingFunction.wrap(Files::lines))
.....
There are several libraries out there that went through the trouble of writing something like the above out for every functional interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With