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

10-03-02 banq
              

类似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
<p>

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

for i in spam:
   L.append(i)
print L
<p>

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

L = map(eggs, spam)
print L
<p>

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;
	}
}
<p>

其中接口MapDelegate如下:

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

客户端使用:

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));
}
<p>

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

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


map.zip

              

2
weidagang2046
2010-03-02 18:58

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

参考:

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

banq
2010-03-03 09:41

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

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