Java中的闭包模拟是否有意义?

Joe*_*e23 8 java

具有闭包的语言(例如Ruby)使得优雅的构造能够转换列表.假设我们有一个班级

class QueryTerm {
  String value;
  public String getValue() {...}
}
Run Code Online (Sandbox Code Playgroud)

以及List<QueryTerm> terms我们想要转换为其值列表的术语列表List<String> values.

在Ruby中我们可以编写如下内容:

values1 = terms.collect do |term|
    term.getValue()
end
Run Code Online (Sandbox Code Playgroud)

Java强制我们构造结果列表并自己遍历术语集合(至少在引入foreach之后没有涉及迭代器或索引位置):

Collection<String> values2 = new HashSet<String>();
for (QueryTerm term : terms) {
    values2.add(term.getValue());
}
Run Code Online (Sandbox Code Playgroud)

Apache CommonsGoogle Collections2尝试使用匿名类来模拟Java中的闭包:

Collection<String> values3 = Collections2.transform(terms, new Function<QueryTerm, String>() {
    @Override
    public String apply(QueryTerm term) {
        return term.getValue();
    }
});
Run Code Online (Sandbox Code Playgroud)

奇怪的是,这个版本有更多的代码行和比原始版本更多的字符!我认为由于这个原因很难理解.因此,当我在Apache Commons中看到它时,我就驳回了这个想法.然而,最近我在谷歌收藏中看到它,我开始怀疑我是否遗漏了一些东西.

因此我的问题是:您对上述结构有何看法?您认为该Collections2.transform()版本比默认版本更易读/可理解吗?我完全错过了什么吗?

最好的问候,约翰内斯

wds*_*wds 5

这里使用的闭包与Command模式几乎相同.我猜这里命令有用的任何原因都适用于此.A当然Command也可能比闭包稍微完全成熟,因为后者仅在功能级别上.但一个关键的观察是,这通常都是你需要的.

有一些优势对我来说很明显:

  • 声明您的操作的功能样式更容易映射到我们对它们的思考方式,即这是我的功能,请将其应用于此数据.
  • 通过透明地使用不同的调用来应用/过滤/转换,从而实现转换的链接.您可以继续将它们链接在一起,并且您可以看到所有操作在一行中相互收集.当然它周围还有许多样板文件,但如果做得好,它对任何java程序员来说都是非常可读的.
  • 控制反转:假设您想要在几个不同的线程上分解您的操作.如果您编写了自己的循环,那么您现在已经陷入困境:您必须自己将其分解为几个不同的循环.编写代码通常很难看,而且需要你创建几个可以传递给其他线程的Runnables.所以你真的只是再次使用封闭装置.

    其中一个JDK7提案显然无法完成这一切,只需提交您的数据并定义要在其上执行的过滤器,您就可以采用它的快乐方式.您实际上可以下载此代码(包extra166y).您可以在javadoc中看到的用于此包的所有操作都可以删除并替换为闭包.所以这是一个很好的例子,为什么某种方法由于缺乏真正的闭包而失败,并且"模拟"闭包不再完全削减它.

实际上,通过传递一个简单的函数可以轻松解决大量问题,这个函数可以执行您希望它对数据执行的操作,并让框架填充其余所有内容.你现在可以使用匿名类来做到这一点,但适当的关闭至少会削减很多锅炉板.

我使用的一个框架使用类似于这种方法来删除大量样板的东西是Spring-Jdbc.在这里,您将JdbcTemplate传递给一个简单的函数,该函数将您的对象从您的对象中删除,ResultSet并将其与您的查询一起传递给它template.query().这减少了许多恶化和通常的JDBC代码的不可读性.如果你要保持这样的话,肯定会获胜.


bru*_*nde 4

IMO,即使有更多的代码行,transform在您的特定示例中,该版本看起来也更具可读性。为什么?因为这个词,转变。您立即知道集合中正在执行转换,而对于普通版本,您必须遵循代码流才能理解其意图。一旦掌握了这些新结构,您就会发现它们更具可读性。