Java 8 函数式编程的技巧

本篇内容

  • 一等成员、高阶方法、科里化以及局部应用
  • 持久化数据结构
  • 生成Java Stream 时的延迟计算和延迟列表
  • 模式匹配以及如何在Java中应用
  • 应用透明性和缓存
1.无处不在的函数

   在前一篇中我们使用术语“函数式编程”意指函数或者方法的行为应该像“数学函数”一样——没有任何副作用。对于使用函数式语言的程序员而言,这个术语的范畴更加宽泛,它还意味着函数可以像任何其他值一样随意使用:可以作为参数传递,可以作为返回值,还能存储在数据结构中。能够像普通变量一样使用的函数称为一等函数(first-class function)。这是Java 8补充的全新内容:通过::操作符,你可以创建一个方法引用,像使用函数值一样使用方法,也能使用Lambda表达式(比如,(int x) -> x + 1)直接表示方法的值。Java 8中使用下面这样的方法引用将一个方法引用保存到一个变量是合理合法的:

Function<String, Integer> strToInt = Integer::parseInt;
1.1 高阶函数

   目前为止,我们使用函数值属于一等这个事实只是为了将它们传递给Java 8的流处理操作,达到行为参数化的效果,Apple::isGreenApple作为参数值传递给filterApples方法那样。但这仅仅是个开始。另一个有趣的例子是静态方法Comparator.comparing的使用,它接受一个函数作为参数同时返回另一个函数(一个比较器),代码如下所示。

Comparator<Apple> c = comparing(Apple::getWeight);

   函数式编程的世界里,如果函数,比如Comparator.comparing,能满足下面任一要求就可以被称为高阶函数(higher-order function):

  • 接受至少一个函数作为参数
  • 返回的结果是一个函数

   这些都和Java 8直接相关。因为Java 8中,函数不仅可以作为参数传递,还可以作为结果返回,能赋值给本地变量,也可以插入到某个数据结构。比如,一个计算口袋的程序可能有这样的一个Map<String, Function<Double, Double>>,它将字符串sin映射到方法Function<Double, Double>,实现对Math::sin的方法引用。

副作用和高阶函数
   在前面我们了解到传递给流操作的函数应该是无副作用的,否则会发生各种各样的问题(比如错误的结果,有时由于竞争条件甚至会产生我们无法预期的结果)。这一原则在你使用高阶函数时也同样适用。编写高阶函数或者方法时,你无法预知会接收什么样的参数——一旦传入的参数有某些副作用,我们将会一筹莫展!如果作为参数传入的函数可能对你程序的状态产生某些无法预期的改变,一旦发生问题,你将很难理解程序中发生了什么;它们甚至会用某种难于调试的方式调用你的代码。因此,将所有你愿意接收的作为参数的函数可能带来的副作用以文档的方式记录下来是一个不错的设计原则,最理想的情况下你接收的函数参数应该没有任何副作用!

1.2 科里化

   它是一种可以帮助你模块化函数、提高代码重用性的技术。

科里化的理论定义

   科里化是一种将具备2个参数(比如,x和y)的函数f转化为使用一个参数的函数g,并且这个函数的返回值也是一个函数,它会作为新函数的一个参数。后者的返

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值