java - 通用编写器/输出器。 Reader 之于 Iterator,Writer 之于 X?

标签 java iterator guava

在 Java 中 Reader 的抽象版本与拉动 对象(而不是字符)一起使用的是 Iterator .

问题是 AppendableWriter 的抽象版本我可以在哪里推送对象(即接口(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的PredicateFunction(尽管这看起来更糟)。它违反了契约(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),您不得不将基本类型的贡献打包,例如 intchar ,这也意味着它们可以为空。考虑注释 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/

相关文章:

java - google guava cachebuilder 在 exipreAfterAccess 和 expireActerWrite 之间使用更长的时间

generics - 在 Scala 参数化(泛型)类型错误中使用 Guava 的简单缓存管理器

java - 在固定超时内缓存单个对象的最佳方法是什么?

java - 如何更改 WebView 高度?

使用 UCanAccess 保存数据时 Java 应用程序挂起

vb.net - 我可以在迭代(使用 For Each)时安全地修改 VB 集合的项目吗?

c++ - 看不懂迭代器的问题?

java - 移动位图不平滑并且不平稳

java - spring web mvc配置问题

c++ - 如何将反向迭代器与作为代理的迭代器一起使用