【问题标题】:Java Iterator backed by network connection网络连接支持的 Java 迭代器
【发布时间】:2012-01-24 21:48:37
【问题描述】:

我发现自己经常编写提供Iterator<Foo> 的API,该Iterator<Foo> 由网络连接支持。该实现打开一个网络连接,从流中读取信息,并将该信息反序列化为Foos 以传递给调用者。不幸的是,总是存在IOException 的可能性,并且还需要优雅地关闭网络连接(当调用者读取最后一个Foo 时可以自动关闭,但如果没有发生呢?)。

已经有几个问题(herehere)关于如何处理将在Iterator 的实现中抛出的检查异常,并且接受的建议是“将它们包装在未经检查的 @987654328 @s”。同时为了允许关闭网络连接,我们可以实现Closeable。所以我们最终得到了这样一个行为良好的异常检查调用者:

Iterator<Foo> iter = null;
try {
    iter = getFooIterator();
    while(iter.hasNext()) {
        Foo foo = iter.next();
        // do something with foo
    }
}
catch(RuntimeException e) {
    if(e.getCause() instanceof IOException) {
       // do something with the IOException
    }
    else throw e;
}
finally {
    if(iter instanceof Closeable) try { ((Closeable)iter).close(); } catch(IOException e) {}
}

实现Iterator 似乎是个好主意。有没有更好的办法?

【问题讨论】:

  • 如果您正在使用 Java 7,您还可以考虑使用 AutoCloseable 并在 try 语句中打开资源,例如try(iter = getFooIterator();) { ... } (尽管迭代器必须实现 AutoCloseable)。
  • 您可能还想考虑在迭代器的方法中关闭连接(例如在next()hasNext() 中),然后抛出异常。这样,迭代器的用户就不必担心关闭迭代器(以及底层连接),而只需处理异常。
  • 不得不承认我不是一个迭代器的大佬(我经常使用集合和简单的数组)。为什么要返回一个带有这些开放式问题的迭代器,而不是一个更简单的 API 的集合?您取回 Collection,一切都已关闭,任何将要发生的异常都会发生。我想我知道答案,但想问...
  • 使用Iterator,调用者可以立即在Foos 上工作。如果有 1000 个 Foos 通过慢速网络连接,这可能会产生重大影响。
  • 我就是这么想的。您可以返回一个作为 BlockingQueue 的集合。但不确定这与迭代器相比是否会有很大的不同。

标签: java iterator


【解决方案1】:

IMO 的第一步是将其包装在特定于实现或应用程序的异常中,从而无需捕获通用 RuntimeExceptions 或检查根本原因。

我会考虑一个特定的实现来避免可关闭的检查并结束IOException

NetworkIterator<Foo> iter = null;
try {
    iter = getFooIterator();
    while (iter.hasNext()) {
        Foo foo = iter.next();
        // do something with foo
    }
} catch (NetworkIteratorExceptiom e) {
    // do something with the IOException
} finally {
    iter.close();
}

我可能不会给它方法让样板消失,但我很想;大致:

NetworkIterator<Foo> iter = new IteratorThang<Foo>() {
    @Override public void each(Foo foo) {
        // Do something with foo
    }
};

【讨论】:

  • 好主意。事实上,我想知道实现java.util.Iterator 是否有任何真正的好处,而不是拥有一个可以抛出检查异常的特定迭代器。 Iterators的消费者多吗?
  • @RobertTupelo-Schneck 各种事情都消耗迭代器;考虑像@​​987654321@这样的东西——像这样的惰性迭代有很多用例。它与在实际需要(可能缓存)之前不会生成后续值的长计算基本相同——它只是来自网络而不是数学(或其他)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 2011-06-24
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多