Java中函数式编程的谓词函数(Predicates)
来源:互联网 发布:访客网络还是 编辑:程序博客网 时间:2024/05/21 10:29
什么是谓词函数?
Apache Commons Collections里的谓词函数仅仅只是一个只有一个方法的接口:
evaluate(Object object):
boolean
这就是谓词函数,输入一个对象,返回true或false。在Google Guava中,定义了Predicate接口,该接口包含一个带有泛型参数的方法:
apply(T input):
boolean
如果想在程序中使用谓词函数,只需要利用自己的逻辑实现该接口即可。
例子:
假设有一个订单列表,每个订单用PurchaseOrder表示,PurchaseOrder中包含日期、顾客和状态。不同的用例要求你有不同的输出,比如获取某个顾客所有等待发货、已发货、已交付或者过去一个小时内完成的订单。当然可以在循环中使用if判断实现这些功能:
//List<PurchaseOrder> orders...public List<PurchaseOrder> listOrdersByCustomer(Customer customer) { final List<PurchaseOrder> selection = new ArrayList<PurchaseOrder>(); for (PurchaseOrder order : orders) { if (order.getCustomer().equals(customer)) { selection.add(order); } } return selection;}以上是获取某个客户所有的订单的代码。不同的功能需要编写多个类似的循环:
public List<PurchaseOrder> listRecentOrders(Date fromDate) { final List<PurchaseOrder> selection = new ArrayList<PurchaseOrder>(); for (PurchaseOrder order : orders) { if (order.getDate().after(fromDate)) { selection.add(order); } } return selection;}这些重复的代码非常明显:除了if的判断条件之外没有任何差异。采用谓词函数的思想在于,利用传入到函数内的谓词的调用替代if语句块里的硬编码的判断条件。这就意味着,你只需要编写带有谓词函数作为参数的方法,就可覆盖所有的甚至你还不知道的测试用例:
public List<PurchaseOrder> listOrders(Predicate<PurchaseOrder> condition) { final List<PurchaseOrder> selection = new ArrayList<PurchaseOrder>(); for (PurchaseOrder order : orders) { if (condition.apply(order)) { selection.add(order); } } return selection;}如果需要考虑到复用,则可以将谓词函数声明成一个单独的类,否则可以把谓词声明成匿名类:
final Customer customer = new Customer("BruceWaineCorp");final Predicate<PurchaseOrder> condition = new Predicate<PurchaseOrder>() { public boolean apply(PurchaseOrder order) { return order.getCustomer().equals(customer); }};Apache或Google的API提供了一个类似java.util.Collections的命名为Collections2的类,它提供了与我们先前编写的代码功能类似的filter()函数,所以可以将方法重构成无循环的版本:
public Collection<PurchaseOrder> selectOrders(Predicate<PurchaseOrder> condition) { return Collections2.filter(orders, condition);}在一个类似的场景中,我们可以要求返回在给定的迭代器之上过滤好的只符合谓词函数的元素的迭代器(装饰模式)。
Iterator filteredIterator = Iterators.filter(unfilteredIterator, condition);Iterable接口和循环使用起来非常方便:
public Iterable<PurchaseOrder> selectOrders(Predicate<PurchaseOrder> condition) { return Iterables.filter(orders, condition);}// you can directly use it in a foreach loop, and it reads well:for (PurchaseOrder order : orders.selectOrders(condition)) { //...}
如果你需要的是判断一个对象是否为空或者不为空的条件,你不需要自己实现一个谓词函数,只需要使用现成的谓词就可以了:
// gives you a predicate that checks if an integer is zeroPredicate<Integer> isZero = Predicates.equalTo(0);// gives a predicate that checks for non null objectsPredicate<String> isNotNull = Predicates.notNull();// gives a predicate that checks for objects that are instanceof the given ClassPredicate<Object> isString = Predicates.instanceOf(String.class);对于给定的谓词,你可以反转它(返回相反的返回值,比如true变成false):
Predicates.not(predicate);利用AND、OR操作结合多个谓词:
Predicates.and(predicate1, predicate2);Predicates.or(predicate1, predicate2);// gives you a predicate that checks for either zero or nullPredicate<Integer> isNullOrZero = Predicates.or(isZero, Predicates.isNull());
阅读全文
1 0
- Java中函数式编程的谓词函数(Predicates)
- 关于谓词函数predicates的介绍
- 谓词函数predicates和仿函数functors
- 谓词函数
- 隐式转换在执行计划中对Access predicates 和Filter predicates 的影响
- 谓词函数、函数对象
- 两个几何谓词判断(predicates)的原理:点与直线的关系&点与圆的关系
- cpp的函数对象和谓词
- 数理逻辑:谓词逻辑(13)Skolem函数
- C++ (1) 函数对象与谓词
- 指定谓词函数排序
- 函数对象 谓词
- C++中的谓词函数
- 函数对象和谓词
- C++函数对象-谓词
- Guava谓词函数
- 谓词 仿函数 函数指针
- 在类的成员函数使用带谓词的sort()函数
- BZOJ 1003 物流运输
- Hadoop简介
- StringUtils中 isNotEmpty 和isNotBlank的区别
- iOS 判断纯数字
- 1298: 分数化小数
- Java中函数式编程的谓词函数(Predicates)
- 数据库连接ORACLE
- 一行代码实现RecyclerView的多选批量操作
- ssm框架的整合(spring ,springMvc,MyBatis)
- Letf join ,right join,inner join的区别
- 时光匆匆,工作一年
- Git 版本管理
- Json介绍
- php实现文件与16进制相互转换