java predicate原理_java8学习之Predicate深入剖析与函数式编程本质

上次【http://www.cnblogs.com/webor2006/p/8214596.html】对Predicate函数接口进行了初步的学习,其中提到了在未来要学习的Stream中得到了大量的应用, 正因为很重要,所以这次再详细的对它进行学习,其中还包含它里面定义的一些默认的方法,为之后的学习打下良好的基础。

这里还是以集合过滤做为例子,该集合存放的全是数字,然后提出四个过滤条件:①、从集合元素中找出所有的奇数;②、从集合元素中找出所有的偶数;③、从集合元素中找出所有大于5的数字;④、从集合元素中找出所有小于3的数字。那试想一下如果采用传统的方式要来实现这些需求是不是得定义若干个过滤方法,伪代码如下:

7aec056c5eccad5ee014e41a0163f145.png

有了Predicate之后,只要定义一个方法既可满足各种过滤条件,如下:

8b461add752f3aa43a0675865d278011.png

接着来调用它来实现我们的各种需求:

19deb7fe79d3b496856a996d664714fc.png

编译运行:

b702ddca668c06c71110a63badf7381a.png

那如果要打印出集合中的所有元素该怎么整呢?直接将条件都置为true不就可以了么,如下:

8b23baae305c26d10ff868ea1fdc036f.png

编译运行:

a952a49e5e8e4ca07d287fc1368ef5ca.png

同理,如果全不打印,则直接返回false既可:

6eba57f158528103a2b9adcf1551e534.png

88988d26333994a6ca9df2a9d70dd05e.png

学这些接口怎么使用是一方面,重点是要通过这些接口的使用体会到函数式编程相比传统编程的一个大的区别:函数式编程是传递行为,而传统的编程是传递值。

当然关于元素的遍历还可以利用Stream来实现,这个在之前已经使用了,不过Stream未来会进行详细的学习的,它跟函数式接口及Lambda表达式是昔昔相关的,这是后话,下面再来看一下Predicate接口的其它默认方法:

and():

先来看一下它的javadoc:

a5917cd088921a397b0f7039de50d660.png

ae46fef42f68b55a0f2d599bdfce6dd3.png

82fc166c34f71e0b842f47f67e93b58f.png

下面看一下它的具体实现:

ed30dcd6dc4b65f2c61e85a2f463416d.png

这个方法就了解到这,具体编码等把正同两个也看完之后再一起举例说明。

negate():

继续看javadoc:

f2aee30399198ccea28f4aaf5d39b897.png

or():

了解了and()操作,其这个方法就比较容易理解了,其实就是一个逻辑或的意思,也只是如果有一个为true则直接返回了,这里就不再读javadoc了,比较容易理解。

好了,下面用代码示例来用一下:

e754bb4c3bd1aa7192feb5d9cfac8f27.png

下面来调用一下它,这里提一个需求:要求找出集合中所有大于5并且是偶数的数字,很明显是由两个且的关系组成,刚好适合咱们定义的这个方法,如下:

1d80ecbdecf19025efdcfd93fe68d230.png

编译运行:

bfa991123ec6ff2f06008e4ec38c1132.png

那如果改成or()呢?也就是找到大于5或者是偶数的元素,如下:

b7fc636f4a01d33ce28415ab891a3a5c.png

再次编译运行:

997c5d04ac2af65c892398cc391bb8ba.png

接下来还是还原则and()操作,这时如果调用一下取反操作呢,如下:

ec1b106848ec99676bcb448fe562fd13.png

编译运行:

8d1c3f6adb93fa92bed8df47ab7efc2e.png

isEqual():

之所以这个最后再说,是因为它不是很重要,实际用得比较少,但是比较难以理解,所以下面也来看一下它的javadoc来理解下:

e9fdfb988b7bff61213468207d6c593b.png

需要注意的是,是指Objects的equals方法,而非Object.equals(),瞅一眼:

3735b437d40c86befca9ec956c3f4d87.png

e8d37400fc77e6554de5b2bcad6e5757.png

下面看下它的具体实现:

1d5d298033aa03d48d62e05a1963046a.png

点击"::"看跳转的是哪?

eebd6feb25c803c2c8b09f5a10b49da8.gif

确实是返回的Predicate类型,那为啥呢?看一下该访问的具体实现:

8bfe73c0cc55065ec9c50aa731fb8152.png

cbafc55f10b6a6048e7d575479ebb4d7.png

那具体它有啥用呢?下面用代码来说明下:

98b4f1e9db3019d37a5b855382049d44.png

44522bd0d4c30166bdc9928a39a26d28.png

编译运行:

e44e6465eb36c6168e1fde7c0b718b8f.png

63d605b00fa2d9ed9ad3aab37e512120.png

很显然返回false:

8ddbd345af8e39243ff1016d0126b2bd.png

d4395eaa38c5cb1d6ace7fcff75c6dd9.png

21a7615be061e3c041b7938f78a1bfb8.png

因为isEqual先调用,test后调用,当然时间上不一致,所以返回false,另外这里理解起来有些绕,下面看下:

a0dee8e24829529fe9bd87982b2efe91.png

8ac564e01b629ae0d4dc0868061c74d4.png

而:

c9fc2f183cbe44b8b8b68facc12ff56a.png

9238e8a006263c98046b0439a32d6f2e.png

所以其equals的逻辑就是如此,这个方法不是特别重要,因为不是太实用,但是由于比较难理解,所以有必要理解理解,对我们对于函数式编程可以起到一定的作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值