使用Java委托实现面向函数式语言中的map/filter

类似Python 这样面向函数式functional语言提供Map/Filter这些函数来实现FP风格编程,好处是在高层次上能够降低代码的复杂性(降低如何做How的复杂性)。

Use delegation to write map/filter in Java(需要翻墙)一文谈了如何使用Java的泛型,通过委托模式来实现面向函数式语言中的Map/Filter类似功能。

首先看一下Map/Filter意思:
1.map(coll, f):通过遍历集合coll,, 调用集合中每个元素f的方法, 将f的方法处理结果装入一个集合返回。
假设Python有一个集合spam 和eggs方法,


spam = ['pork','ham','spices']
numbers = [1,2,3,4,5]

def eggs(item):
return item

那么如果我们要获得集合spam输出,无疑要遍历这个集合:

for i in spam:
L.append(i)
print L

而使用map函数,就只需一句话:

L = map(eggs, spam)
print L

2.filter(coll, f) 类似map功能,遍历这个集合,调用f,当f返回是真条件,才会把结果放入返回集合中。

map/filter真的帮助我们减少了大量循环遍历垃圾编码的编写,还有更多精简功能:
比如你有一个用户集合,你需要返回用户的id,作为id集合返回;然后你又需要返回用户的姓名name集合,每个功能你都要实现一遍,如果再要返回用户的年龄集合,你又要做一遍,琐碎细节代码充斥在软件系统中。

Use delegation to write map/filter in Java一文通过使用泛型和一个委托接口MapDelegate类来实现map函数,如下:


public class Mapper {

<FromType, ToType> List<ToType> map(List<FromType> list, MapDelegate<FromType, ToType> mapDelegate) {
List<ToType> retval = new ArrayList<ToType>(list.size());
for (FromType item : list) {
retval.add(mapDelegate.map(item));
}
return retval;
}
}

其中接口MapDelegate如下:

public interface MapDelegate<FromType, ToType> {
ToType map(FromType obj);
}

客户端使用:

public static void main(String[] args) {

List qs = new ArrayList();
qs.add(new Q("afv"));
qs.add(new Q(
"edsd"));
qs.add(new Q(
"eedd"));

Mapper mapper = new Mapper();

List<String> ids = mapper.map(qs, new MapDelegate<Q, String>() {
public String map(Q q) {
return new StringBuilder(q.getV()).toString();
}
});

System.out.print(
"ids=" + ids.get(1));
}

以上代码我经过调试可运行。代码见下面附件。


[该贴被banq于2010-03-02 15:22修改过]
attachment:


map.zip

Java还没有闭包支持,所以文中这种方法的功能还是有局限。如果支持闭包,文中的public String map(Q q)方法内部就可以直接引用其上下文中的局部变量(如:qs)。

参考:
http://www.ibm.com/developerworks/cn/java/j-jtp04247.html

Java 理论与实践: 闭包之争 这篇文章不错。受教了,谢谢。

内部类和闭包Closure/lambda还是有距离的,闭包能够更好支持对象职责和行为,同时能够将透明性和What/How分离巧妙结合在一起。因为隐藏How实现,语言级别的并行计算就成为可能。