传递代码

我们首先看一个例子,假设你有一个 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)相关推荐

  1. c语言 谓词,C++ 谓词(predicate) 与 仿函数 ( functor (function object))

    #谓词与函数对象 谓词 predicate C++ 标准定义谓词如下: The Predicate parameter is used whenever an algorithm expects a ...

  2. Java 8 基础教程 - Predicate,java基础面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  3. C++谓词(一元谓词,二元谓词)

    谓词 谓词 一元谓词 二元谓词 谓词 概念: 1.返回bool类型的仿函数称为谓词 2.如果operator()接受一个参数,那么叫做一元谓词 3.如果operator()接受两个参数,那么叫做二元谓 ...

  4. java 谓词_谓词::不适合Java

    java 谓词 Jim Laskey在OpenJDK core-libs-dev邮件列表上最近的消息" RFR:CSR – JDK-8203428 Predicate :: not &quo ...

  5. java 8 谓词_Java谓词– Java 8谓词

    java 8 谓词 In this article, we'll talk about Java Predicate, which is a Functional Interface. A Funct ...

  6. c语言 谓词,iOS 谓词(Predicate)指南

    Edit this DociOS 谓词(Predicate) 在查看 '-ios uiautomation' 搜索策略时了解 谓词(Predicate) 十分必要. UIAutomation Java ...

  7. 谓词推进 PUSHED PREDICATE

    UNION ALL PUSHED PREDICATE 谓词前推. 讲谓词推进 UNION ALL 的操作中 可以通过index 在union 之前 访问表 减少 union 和filter 的成本. ...

  8. 一阶逻辑与二阶逻辑的区别一元谓词多元谓词

    https://blog.csdn.net/lengye7/article/details/89709244 命题逻辑 零阶逻辑 表达句子与句子间的关系 一阶对个体的(量词)修饰 对于所有的个体 三段 ...

  9. Optional java 用法_Java8 Optional 的正确使用方式

    1.当我们还在以如下几种方式使用 Optional 时, 就得开始检视自己了 调用 isPresent() 方法时 调用 get() 方法时 Optional 类型作为类/实例属性时 Optional ...

  10. Java 8里的Predicate学习笔记

    测试代码: MapTest maptest = new MapTest();List<Country> testdata = maptest.getCountry();Map<Str ...

最新文章

  1. 网络编程 -- gethostbyname() 函数解析
  2. Python实现最简单的文字游戏
  3. 前端学习(2152):Vue的template和el的关系
  4. 无心剑中译杰克•谢弗《当默多克遇到撒旦》
  5. BIM 360 Docs API在操作欧洲数据中心内容的一些调整
  6. servlet 从oracle中结果集,用servlet对oracle进行增删改查
  7. WebService 服务 转
  8. 记一次jenkins构建无权限问题
  9. CGAN和InfoGAN理解
  10. HTML 调用打印机打印指定区域
  11. 2011英语一长难句
  12. STM32F4+W25Q64实现一个U盘
  13. 下一代数据架构Data Fabric到底是什么?
  14. 深入boot.img格式文件结构解析
  15. 仿 手机QQ 登录、注册、找回密码、好友列表、QQ状态等功能的实现
  16. 《计算之魂》读书笔记 04
  17. 微信小程序实现点赞与取消点赞功能
  18. 还不清楚视频如何转文字?借助这3款软件可以实现
  19. MIME格式详细介绍
  20. 单片机看门狗工作原理

热门文章

  1. Linux下编译、链接、加载运行C++ OpenCV的两种方式及常见问题的解决
  2. curl 的用法指南
  3. python图像识别代码_用Python进行简单图像识别(验证码)
  4. c标签判断true false jsp_Java学习知识点:小白如何掌握JSP技术?
  5. 2017 到 2018,PWA 技术到底经历了什么
  6. 你不知道的js中关于this绑定机制的解析[看完还不懂算我输]
  7. 升级PowerShell至4.0版本
  8. JEESZ分布式架构3--CentOs下安装MySQL(环境准备)
  9. Feature selection
  10. [CareerCup] 8.10 Implement a Hash Table 实现一个哈希表