Mar*_*mus 5 java java-8 try-with-resources java-stream
我正在创建多个流,我必须并行(或可能并行)访问.我知道如何在编译时修复资源量时尝试使用资源,但是如果资源量由参数确定怎么办?
我有这样的事情:
private static void foo(String path, String... files) throws IOException {
@SuppressWarnings("unchecked")
Stream<String>[] streams = new Stream[files.length];
try {
for (int i = 0; i < files.length; i++) {
final String file = files[i];
streams[i] = Files.lines(Paths.get(path, file))
.onClose(() -> System.out.println("Closed " + file));
}
// do something with streams
Stream.of(streams)
.parallel()
.flatMap(x -> x)
.distinct()
.sorted()
.limit(10)
.forEach(System.out::println);
}
finally {
for (Stream<String> s : streams) {
if (s != null) {
s.close();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以编写一个复合AutoCloseable来管理动态数量AutoCloseable:
import java.util.ArrayList;
import java.util.List;
public class CompositeAutoclosable<T extends AutoCloseable> implements AutoCloseable {
private final List<T> components= new ArrayList<>();
public void addComponent(T component) { components.add(component); }
public List<T> getComponents() { return components; }
@Override
public void close() throws Exception {
Exception e = null;
for (T component : components) {
try { component.close(); }
catch (Exception closeException) {
if (e == null) { e = closeException; }
else { e.addSuppressed(closeException); }
}
}
if (e != null) { throw e; }
}
}
Run Code Online (Sandbox Code Playgroud)
你可以在你的方法中使用它:
private static void foo(String path, String... files) throws Exception {
try (CompositeAutoclosable<Stream<String>> streams
= new CompositeAutoclosable<Stream<String>>()) {
for (int i = 0; i < files.length; i++) {
final String file = files[i];
streams.addComponent(Files.lines(Paths.get(path, file))
.onClose(() -> System.out.println("Closed " + file)));
}
streams.getComponents().stream()
.parallel()
.flatMap(x -> x)
.distinct()
.sorted()
.limit(10)
.forEach(System.out::println);
}
}
Run Code Online (Sandbox Code Playgroud)