我读了一篇关于Joel On Software的文章,关于使用高阶函数通过使用map和reduce大大简化代码的想法。他提到在Java中这很难做到。文章:http://www.joelonsoftware.com/items/2006/08/01.html
下面的文章中的示例循环遍历数组,并使用作为数组中每个元素的参数传递的函数fn:
function map(fn, a)
{
for (i = 0; i < a.length; i++)
{
a[i] = fn(a[i]);
}
}
在实践中,这将被调用类似于以下内容:
map( function(x){return x*2;}, a );
map( alert, a );
理想情况下,我想编写一个map函数来处理数组,或者尽可能编写任何类型的集合。
我一直在互联网上四处看看,我很难找到有关这个主题的资源。首先,java中的匿名函数是否可行?这有可能以另一种方式吗?它将在未来的java版本中提供吗?如果可能的话,我该怎么做?
我想如果在Java中这是不可能的,人们会用某种“模式”/技术来达到同样的效果,因为我认为匿名函数在软件世界中是一个非常强大的工具。我能找到的唯一类似的问题是:Java generics - implementing higher order functions like map这对我来说完全没有意义。
答案 0 :(得分:6)
Guava提供了地图(但它的名称为transform
,而且位于Lists
和Collections2
等实用程序类中。但是,它不提供折叠/缩小。
无论如何,与在Scheme中使用transform
相比,使用map
的语法非常笨拙。如果你是右撇子,这有点像用左手写字。但是,这是Java;你能指望什么。 :-P
答案 1 :(得分:3)
单方法匿名类提供了一种类似但更冗长的Java编写匿名函数的方法。 例如,您可以:
Iterable<Source> foos = ...;
Iterable<Destination> mappedFoos = foos.map(new Function<Source, Destination>()
{
public Destination apply(Source item) { return ... }
});
有关具有功能样式的Java库的示例,请参阅Guava
答案 2 :(得分:2)
答案 3 :(得分:2)
interface Func<V,A> {
V call (A a);
}
static <V,A> List<V> map (Func<V,A> func, List<A> as) {
List<V> vs = new ArrayList<V>(as.size());
for (A a : as) {
Vs.add(func.call(a));
}
return vs;
}
答案 4 :(得分:0)
Paguro has an open-source implementation of higher order functions。初始测试显示它的速度是原生Java forEach循环的98%。它支持的操作是懒惰地应用而不修改底层集合。它输出到不可变(有时是可变的)Clojure集合的类型安全版本。 Transformable is built into Paguro's unmodifiable and immutable collections and interfaces。要使用原始java.util集合作为输入,只需使用xform()
函数进行包装即可。