将 AutoCloseable、Iterable class 转换为 Stream
Converting an AutoCloseable, Iterable class into a Stream
StreamSupport.stream()
可以从 Iterable
创建 Stream
,但是如果 class 实现了 Iterable
和 AutoCloseable
呢?是否可以将 class 转换为 Stream
并在 try-with-resources 块中构建它?
public class NonWorkingExample {
public static void main(final String[] args) {
// this won't call MyCursor.close()
try (Stream<String> stream = StreamSupport.stream(new MyCursor().spliterator(), false)) {
stream.forEach(System.out::println);
}
}
private static class MyCursor implements AutoCloseable, Iterable<String> {
public void close() throws Exception {
System.out.println("close");
}
public Iterator<String> iterator() {
List<String> items = new ArrayList<>();
items.add("foo");
items.add("bar");
items.add("baz");
return items.iterator();
}
}
}
As stated in the javadoc, BaseStream.onClose()
“Returns 具有额外关闭处理程序的等效流”:
public class WorkingExample {
public static void main(final String[] args) {
MyCursor cursor = new MyCursor();
try (Stream<String> stream = StreamSupport.stream(cursor.spliterator(), false)
.onClose(cursor::close)) {
stream.forEach(System.out::println);
}
}
}
将根据需要调用 MyCursor.close()
。
StreamSupport.stream()
可以从 Iterable
创建 Stream
,但是如果 class 实现了 Iterable
和 AutoCloseable
呢?是否可以将 class 转换为 Stream
并在 try-with-resources 块中构建它?
public class NonWorkingExample {
public static void main(final String[] args) {
// this won't call MyCursor.close()
try (Stream<String> stream = StreamSupport.stream(new MyCursor().spliterator(), false)) {
stream.forEach(System.out::println);
}
}
private static class MyCursor implements AutoCloseable, Iterable<String> {
public void close() throws Exception {
System.out.println("close");
}
public Iterator<String> iterator() {
List<String> items = new ArrayList<>();
items.add("foo");
items.add("bar");
items.add("baz");
return items.iterator();
}
}
}
As stated in the javadoc, BaseStream.onClose()
“Returns 具有额外关闭处理程序的等效流”:
public class WorkingExample {
public static void main(final String[] args) {
MyCursor cursor = new MyCursor();
try (Stream<String> stream = StreamSupport.stream(cursor.spliterator(), false)
.onClose(cursor::close)) {
stream.forEach(System.out::println);
}
}
}
将根据需要调用 MyCursor.close()
。