供一个一般性的接口,通过编写这个接口的特定实现创建具体的闭包。在第二种技术 表达式合成(expression composition) 中,基础设施提供实现了基本一元/二元/三元/.../n 元操作(比如一元操作符 not 和二元操作符 and / or )的具体帮助类。在这里,新的闭包由这些基本构建块的任意组合创建而成。
我将在下面的几节中详细讨论这两种技术。
Java语言中的函数编程(3)
时间:2011-01-31 IBM Abhijit Belapurkar
表达式特化
假定您在编写一个在线商店的应用程序。商店中可提供的商品用类 SETLItem 表示。每一件商品都有相关的标签价格, SETLItem 类提供了名为 getPrice 的方法,对商品实例调用这个方法时,会返回该商品的标签价格。
如何检查 item1 的成本是否不低于 item2 呢?在 Java 语言中,一般要编写一个像这样的表达式:
assert(item1.getPrice() >= item2.getPrice());
像这样的表达式称为 二元谓词(binary predicate), 二元是因为它取两个参数,而 谓词 是因为它用这两个参数做一些事情并生成布尔结果。不过要注意,只能在执行流程中执行上面的表达式,它的输出取决于 item1 和 item2 在特定瞬间的值。从函数编程的角度看,这个表达式还不是一般性的逻辑,就是说,它不能不管执行控制的当前位置而随心所欲地传递并执行。
为了使二元谓词发挥作用,必须将它封装到一个对象中,通过 特化(specializing) 一个称为 BinaryPredicate 的接口做到这一点,这个接口是由 Apache Functor 库提供的,如清单 2 所示。
清单 2. 表达式特化方法
package com.infosys.setl.fp;
public class SETLItem
{
private String name;
private String code;
private int price;
private String category;
public int getPrice()
{
return price;
}
public void setPrice(int inPrice)
{
price = inPrice;
}
public String getName()
{
return name;
}
public void setName(String inName)
{
name = inName;
}
public String getCode()
{
return code;
}
public void setCode(String inCode)
{
code = inCode;
}
public String getCategory()
{
return category;
}
public void setCategory(String inCategory)
{
category = inCategory;
}
}
package com.infosys.setl.fp;
import java.util.Comparator;
public class PriceComparator implements Comparator
{
public int compare (Object o1, Object o2)
{
return (((SETLItem)o1).getPrice()-((SETLItem)o2).getPrice());
}
}
package com.infosys.setl.fp;
import org.apache.commons.functor.*;
import org.apache.commons.functor.core.comparator.*;
import java.util.*;
public class TestA
{
public static void main(String[] args)
{
try
{
Comparator pc = new PriceComparator();
BinaryPredicate bp = new IsGreaterThanOrEqual(pc);
SETLItem item1 = new SETLItem();
item1.setPrice(100);
SETLItem item2 = new SETLItem();
item2.setPrice(99);
if (bp.test(item1, item2))
System.out.println("Item1 costs more than Item2!");
else
System.out.println("Item2 costs more than Item1!");
SETLItem item3 = new SETLItem();
item3.setPrice(101);
if (bp.test(item1, item3))
System.out.pri
|