java 谓词_java8-谓词(predicate)
传递代码
我们首先看一个例子,假设你有一个 Apple 类,它有一个getColor方法,还有一个变量inventory保存着一个Apples的列表。你可能想要选出所有的绿苹果,并返回一个列表。通常我们用筛选(filter)一词来表达这个概念。在 Java 8之前,你可能会写这样一个方法 filterGreenApples :
public static List filterGreenApples(List inventory){
List result = new ArrayList<>();
for (Apple apple: inventory){
if ("green".equals(apple.getColor())) {
result.add(apple);
}
}
return result;
}
但是接下来,有人可能想要选出重的苹果,比如超过150克,于是你心情沉重地写了下面这
个方法,甚至用了复制粘贴:
public static List filterHeavyApples(List inventory){
List result = new ArrayList<>();
for (Apple apple: inventory){
if (apple.getWeight() > 150) {
result.add(apple);
}
}
return result;
}
我们都知道软件工程中复制粘贴的危险——给一个做了更新和修正,却忘了另一个。嘿,这
两个方法只有一行不同: if 里面高亮的那行条件。如果这两个高亮的方法之间的差异仅仅是接受
的重量范围不同,那么你只要把接受的重量上下限作为参数传递给 filter 就行了,比如指定
(150, 1000) 来选出重的苹果(超过150克),或者指定 (0, 80) 来选出轻的苹果(低于80克)。
但是,我们前面提过了,Java 8会把条件代码作为参数传递进去,这样可以避免 filter 方法
出现重复的代码。现在你可以写:
public static boolean isGreenApple(Apple apple) {
return "green".equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple) {
return apple.getWeight() > 150;
}
static List filterApples(List inventory, Predicate p) {
List result = new ArrayList<>();
for (Apple apple: inventory){
if (p.test(apple)) {
result.add(apple);
}
}
return result;
}
要用它的话,你可以写:
filterApples(inventory, Apple::isGreenApple);
或者
filterApples(inventory, Apple::isHeavyApple);
什么是谓词?
前面的代码传递了方法 Apple::isGreenApple (它接受参数 Apple 并返回一个
boolean )给 filterApples ,后者则希望接受一个 Predicate 参数。词 谓词(predicate)
在数学上常常用来代表一个类似函数的东西,它接受一个参数值,并返回 true 或 false 。你
在后面会看到,Java 8也会允许你写 Function ——在学校学过函数却没学
过谓词的读者对此可能更熟悉,但用 Predicate 是更标准的方式,效率也会更高一
点儿,这避免了把 boolean 封装在 Boolean 里面。
从传递方法到 Lambda
把方法作为值来传递显然很有用,但要是为类似于 isHeavyApple 和 isGreenApple 这种可
能只用一两次的短方法写一堆定义有点儿烦人。不过Java 8也解决了这个问题,它引入了一套新
记法(匿名函数或Lambda),让你可以写
filterApples(inventory, (Apple a) -> "green".equals(a.getColor()) );
或者
filterApples(inventory, (Apple a) -> a.getWeight() > 150 );
甚至
filterApples(inventory, (Apple a) -> a.getWeight() < 80 ||
"brown".equals(a.getColor()) );
完整的代码为:
public class FilteringApples1 {
public static void main(String[] args) {
List inventory = Arrays.asList(new FilteringApples1.Apple(80, "green"),
new FilteringApples1.Apple(155, "green"),
new FilteringApples1.Apple(120, "red"));
List greenApples2 = filterApples(inventory, (FilteringApples1.Apple a) -> "green".equals(a.getColor()));
System.out.println(greenApples2);
// [Apple{color='green', weight=155}]
List heavyApples2 = filterApples(inventory, (FilteringApples1.Apple a) -> a.getWeight() > 150);
System.out.println(heavyApples2);
// []
List weirdApples = filterApples(inventory, (FilteringApples1.Apple a) -> a.getWeight() < 80 ||
"brown".equals(a.getColor()));
System.out.println(weirdApples);
}
public static List filterApples(List inventory, Predicate p) {
List result = new ArrayList<>();
for (FilteringApples1.Apple apple : inventory) {
if (p.test(apple)) {
result.add(apple);
}
}
return result;
}
public static class Apple {
private int weight = 0;
private String color = "";
public Apple(int weight, String color) {
this.weight = weight;
this.color = color;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String toString() {
return "Apple{" +
"color='" + color + '\'' +
", weight=" + weight +
'}';
}
}
}
java8中内置filter函数
static Collection filter(Collection c, Predicate p);
这样你甚至都不需要写 filterApples 了,因为比如先前的调用
filterApples(inventory, (Apple a) -> a.getWeight() > 150 );
就可以直接调用库方法 filter :
filter(inventory, (Apple a) -> a.getWeight() > 150 );
java 谓词_java8-谓词(predicate)相关推荐
- c语言 谓词,C++ 谓词(predicate) 与 仿函数 ( functor (function object))
#谓词与函数对象 谓词 predicate C++ 标准定义谓词如下: The Predicate parameter is used whenever an algorithm expects a ...
- Java 8 基础教程 - Predicate,java基础面试笔试题
我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...
- C++谓词(一元谓词,二元谓词)
谓词 谓词 一元谓词 二元谓词 谓词 概念: 1.返回bool类型的仿函数称为谓词 2.如果operator()接受一个参数,那么叫做一元谓词 3.如果operator()接受两个参数,那么叫做二元谓 ...
- java 谓词_谓词::不适合Java
java 谓词 Jim Laskey在OpenJDK core-libs-dev邮件列表上最近的消息" RFR:CSR – JDK-8203428 Predicate :: not &quo ...
- java 8 谓词_Java谓词– Java 8谓词
java 8 谓词 In this article, we'll talk about Java Predicate, which is a Functional Interface. A Funct ...
- c语言 谓词,iOS 谓词(Predicate)指南
Edit this DociOS 谓词(Predicate) 在查看 '-ios uiautomation' 搜索策略时了解 谓词(Predicate) 十分必要. UIAutomation Java ...
- 谓词推进 PUSHED PREDICATE
UNION ALL PUSHED PREDICATE 谓词前推. 讲谓词推进 UNION ALL 的操作中 可以通过index 在union 之前 访问表 减少 union 和filter 的成本. ...
- 一阶逻辑与二阶逻辑的区别一元谓词多元谓词
https://blog.csdn.net/lengye7/article/details/89709244 命题逻辑 零阶逻辑 表达句子与句子间的关系 一阶对个体的(量词)修饰 对于所有的个体 三段 ...
- Optional java 用法_Java8 Optional 的正确使用方式
1.当我们还在以如下几种方式使用 Optional 时, 就得开始检视自己了 调用 isPresent() 方法时 调用 get() 方法时 Optional 类型作为类/实例属性时 Optional ...
- Java 8里的Predicate学习笔记
测试代码: MapTest maptest = new MapTest();List<Country> testdata = maptest.getCountry();Map<Str ...
最新文章
- 网络编程 -- gethostbyname() 函数解析
- Python实现最简单的文字游戏
- 前端学习(2152):Vue的template和el的关系
- 无心剑中译杰克•谢弗《当默多克遇到撒旦》
- BIM 360 Docs API在操作欧洲数据中心内容的一些调整
- servlet 从oracle中结果集,用servlet对oracle进行增删改查
- WebService 服务 转
- 记一次jenkins构建无权限问题
- CGAN和InfoGAN理解
- HTML 调用打印机打印指定区域
- 2011英语一长难句
- STM32F4+W25Q64实现一个U盘
- 下一代数据架构Data Fabric到底是什么?
- 深入boot.img格式文件结构解析
- 仿 手机QQ 登录、注册、找回密码、好友列表、QQ状态等功能的实现
- 《计算之魂》读书笔记 04
- 微信小程序实现点赞与取消点赞功能
- 还不清楚视频如何转文字?借助这3款软件可以实现
- MIME格式详细介绍
- 单片机看门狗工作原理
热门文章
- Linux下编译、链接、加载运行C++ OpenCV的两种方式及常见问题的解决
- curl 的用法指南
- python图像识别代码_用Python进行简单图像识别(验证码)
- c标签判断true false jsp_Java学习知识点:小白如何掌握JSP技术?
- 2017 到 2018,PWA 技术到底经历了什么
- 你不知道的js中关于this绑定机制的解析[看完还不懂算我输]
- 升级PowerShell至4.0版本
- JEESZ分布式架构3--CentOs下安装MySQL(环境准备)
- Feature selection
- [CareerCup] 8.10 Implement a Hash Table 实现一个哈希表