在 Java 中 Reader
的抽象版本与拉动 对象(而不是字符)一起使用的是 Iterator
.
问题是 Appendable
或 Writer
的抽象版本我可以在哪里推送对象(即接口(interface))?
过去我只是把自己的界面做成这样:
public interface Pusher<T> {
public void push(T o);
}
是否有一个在大多数环境中都可用的通用接口(interface),有人知道它有意义,这样我就不必继续创建上述接口(interface)了吗?
更新:
这是一个有用的例子:
public void findBadCategories(final Appendable a) {
String q = sql.getSql("product-category-bad");
jdbcTemplate.query(q, new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
String id = rs.getString("product_category_id");
String name = rs.getString("category_name");
if (! categoryMap.containsKey(id)) {
try {
a.append(id + "\t" + name + "\n");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
});
}
我在这里使用的是 Appendable
,但我更愿意使用 Pusher
回调。相信我一次Java 8 comes out I would just use closure but that closure still needs an interface .
最后我之前选择的另一个选项是完全违反Guava的Predicate
或 Function
(尽管这看起来更糟)。它违反了契约(Contract),因为这些旨在实现幂等(尽管我想如果你一直返回 true
......)。
不过,Guava 提供的功能有点类似于 Python 的生成器,这要归功于它的 AbstractIterator。 .
我添加了一个 enhancement issue to Guava但我同意他们的看法,他们的工作并不是添加这样的基本内容。
最佳答案
现在在几个项目中,我为此目的定义了我称之为sink的东西:
interface Sink<T> {
void put(T contribution);
}
由此,生成类型为 T
的对象的方法需要一个类型为 Sink<? super T>
的参数.
出现了几个设计问题:
声明,
Sink#put()
不抛出检查异常。这不适用于通常抛出IOException
的 I/O 操作。 .要解决此问题,您可以添加一个扩展Exception
的类型参数并宣传put()
抛出此类型,但此时,如果您对值(value)消费的本质了解很多,您可能最好为它定义一个自定义接口(interface)。声明,
Sink#put()
不返回值。无法向调用方指示该值是否已被接受。使用这样的通用接口(interface),您不得不将基本类型的贡献打包,例如
int
和char
,这也意味着它们可以为空。考虑注释contribution
参数与@NonNull
.
为了配合这种类型,与 Petr Pudlák 在他的回答中提到的 generator 概念相关,我定义了一个source 接口(interface):
interface Source<T> {
T get();
}
寻找绘制 T
类型项目的方法从这样的来源需要一个类型为 Source<? extends T>
的参数.
为了协调并发进程之间的 channel ,我定义了 Sink#put()
和 Source#get()
扔InterruptedException
:
interface Sink<T> {
void put(T contribution) throws InterruptedException;
}
interface Source<T> {
T get() throws InterruptedException;
}
这些类似于 Doug Lea's original Puttable
和 Takable
未进入 java.util.concurrent
的接口(interface)包,虽然缺少等同于定时等待 Puttable#offer()
和 Takable#poll()
方法。
然后出现了各种可以轻松组合的实现,例如交换器、过滤器和转换器。
除了我自己的图书馆,我还看到 Guava 图书馆提供了 PrimitiveSink
和 Funnel
hashing-related purposes 的类型.您可能会发现这些也是有用的抽象。
关于java - 通用编写器/输出器。 Reader 之于 Iterator,Writer 之于 X?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12198546/