Pie*_*rre 32 java resources iterator
我已经 使用应该使用方法在最后发布的资源实现了自定义java.util.Iteratorclose()
.该资源可以是java.sql.ResultSet,java.io.InputStream等...
public interface CloseableIterator<T> extends Iterator<T>
{
public void close();
}
Run Code Online (Sandbox Code Playgroud)
使用此迭代器的某些外部库可能不知道必须关闭它.例如:
public boolean isEmpty(Iterable<T> myiterable)
{
return myiterable.iterator().hasNext();
}
Run Code Online (Sandbox Code Playgroud)
在那种情况下,有没有办法关闭这个迭代器?
更新:非常感谢您当前的答案.我会给每个人一个(+1).当hasNext()返回false 时,我已经关闭了Iterator .我的问题是当循环迭代在最后一次迭代之前中断时,如我的例子中所示.
Nic*_*rot 21
创建一个实现AutoCloseable接口的自定义迭代器
public interface CloseableIterator<T> extends Iterator<T>, AutoCloseable {
}
Run Code Online (Sandbox Code Playgroud)
然后在try with resource语句中使用此迭代器.
try(CloseableIterator iterator = dao.findAll()) {
while(iterator.hasNext()){
process(iterator.next());
}
}
Run Code Online (Sandbox Code Playgroud)
无论发生什么情况,这种模式都将关闭底层资源: - 语句完成后 - 即使抛出异常
最后,清楚地记录必须如何使用此迭代器.
如果您不想委派关闭呼叫,请使用推送策略.例如.用java 8 lambda:
dao.findAll(r -> process(r));
Run Code Online (Sandbox Code Playgroud)
Osc*_*Ryz 14
在你的实现中,如果迭代器耗尽,你可以将它自己关闭.
public boolean hasNext() {
....
if( !hasNext ) {
this.close();
}
return hasNext;
}
Run Code Online (Sandbox Code Playgroud)
并清楚地记录:
当hasNext()返回false时,此迭代器将调用close(),如果您需要先处置迭代器,请确保调用close close your self
例:
void testIt() {
Iterator i = DbIterator.connect("db.config.info.here");
try {
while( i.hasNext() {
process( i.next() );
}
} finally {
if( i != null ) {
i.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,你可以在那里实现Iterable并使用增强的for循环.
问题是最后的情况.我们经常迭代完整的集合或数据集,所以我们现在已经到了最后,没有数据可供阅读.
但是如果我们在到达数据结束之前设置了循环中断,则迭代器将不会结束并且不会被关闭.
一种出路可能是在构造期间将数据源的内容缓存在迭代器中并关闭资源.因此迭代器不会对打开的资源起作用,而是对缓存的数据起作用.
如果可能,将迭代器包装在 Stream 中,这样您就可以访问onClose
流的方法。然后您应该将关闭逻辑移至该方法中并在那里进行清理。
例子:
StreamSupport.stream(Spliterators.spliteratorUnknownSize(
new MyCustomIterator<T>(), 0), false).onClose(() -> {
// close logic here
});
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15934 次 |
最近记录: |