On 11/18/2013 03:28 PM, Brian Goetz wrote:
Which means that, if your stream holds non-memory resources, the flatMapper should create a stream that closes the underlying stream, like:

  blah.flatMap(path -> {
     BufferedReader br = new BufferedReader(path);
     return br.lines.onClose(br::close);
  }
...

...the only problem with above code is that it doesn't compile, because of IOException declared on BufferedReader (FileReader actually!) constructor and BufferedReader.close() method. The solutions to this have already been discussed on the list some time ago, and one of the propositions was to create interfaces like:


public interface IOFunction<T, R> extends Function<T, R> {
    default R apply(T t) {
        try {
            return applyIO(t);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    R applyIO(T t) throws IOException;
}


public interface IORunnable  extends Runnable {
    default void run() {
        try {
            runIO();
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    void ruinIO() throws IOException;
}


...etc, and use them in code like this:


List<String> paths = ...
paths
    .stream()
    .flatMap((IOFunction<String, Stream<String>>) path -> {
        BufferedReader br = new BufferedReader(new FileReader(path));
        return br.lines().onClose((IORunnable) br::close);
    })
    .forEach(System.out::println);



Regards, Peter


Reply via email to