Groovy 学习手册(5)

摘要:
关注功能并最小化状态变化(使用不可变数据结构)。函数式编程可以被视为命令式编程的更常见的替代方案。Scala支持通过lambda和函数接口进行函数编程。在基本的函数式编程语言中,闭包被用作方法的最后一个参数。定义了一个方法来使用闭包过滤列表中的元素。

8. 函数式编程

函数式编程(FP)是一种编程风格,侧重于函数和最小化状态的变化(使用不可变的数据结构)。它更接近于用数学来表达解决方案,而不是循序渐进的操作。
在函数式编程里,其功能应该是“无副作用”(不会改变外部功能),参考透明的(一个函数每次传递相同的参数,返回相同的值)。

函数式编程可以被看作是一种更常见的命令式编程的替代,它更接近告诉计算机遵循每个步骤。

虽然函数式编程可以在Java 8 前实现,但在 Java 8 版本,通过 Lambda 和函数接口,才真正在语言层面上支持函数式编程。
Java 8、JavaScript、Groovy,Scala都支持函数式编程,他们虽然并不是严格意义上的函数式编程语言。

1. 函数和闭包

也许你也知道,在基本的函数式编程的语言里,函数才是第一等公民,这意味着函数可以在任何地方使用。
例如,在JavaScript里,你可以把一个函数指定给一个变量,并执行它:

var func = function(x) { return x + 1; }
var three = func(2); //3

尽管在 Groovy 里,函数并不具备第一等公民的特性,但有功能相似的方式实现:闭包。闭包就是在一对大括号里面包含的在“->”左边带有参数的代码块。例如:

def  closr = {x -> x + 1}
println( closr(2) ); //3

在 Groovy 里,如果闭包只有一个参数,那么默认 it就作为这个参数的引用,例如:

def  closr = {it + 1}

Tip
如果返回值是最后一个表达式,则return 关键字可以省略。

使用闭包

如果闭包作为方法的最后一个参数,或者方法只有一个参数,这种情况下,闭包的实现可以放在括号的外面,例如,下面的代码,定义了一个方法用来使用闭包对 List 里面的元素进行过滤:

def  find(list, tester) {
    for (item in list)
        if (tester(item)) return item
}

这个方法返回当闭包条件为 true时的第一个元素,下面就是调用的此闭包的代码:

 find([1,2,]) { it > 1 } // 2

映射 / 过滤 / 其他

一旦你掌握了函数,你很快会意识到需要一种方法来执行数据集合(或序列或数据流)的操作。
由于有些都是常见的操作,人们发明了顺序操作,如映射,过滤,聚合等操作。
下面的例子里,使用一个装有多个 Person对象的 List 集合来演示这些操作。

Groovy 学习手册(5)第1张
map(collect方法):把输入元素转化或改变成其他形式的元素。
Groovy 学习手册(5)第2张
filter(findAll方法):当 predicate 函数式接口为 true 时返回子集合。
Groovy 学习手册(5)第3张
reduce(inject方法):在元素上进行聚合操作(返回一个结构,例如所有元素的总和)。

Groovy 学习手册(5)第4张
Limit([0..n-1]):返回前 n 个元素。

Groovy 学习手册(5)第5张
Concat(+):结合两个不同的元素集合。

class Person { String name; int age }

def persons = [new Person(name:'Bob',age:20), new Person(name:'Tom',age:15)]

def names = persons.collect { person -> person.name }
def adults = persons.findAll { person -> return person.age >= 18 }
def totalAge = persons.inject(0){total, p -> return total + p.age}

上面的代码中,使用了inject方法,它会循环遍历每一个 List 中的元素,最后返回一个值。我们给total赋了一个初始值为0,最后我们把每个 Person 的年龄全部加起来得到一个总和。

免责声明:文章转载自《Groovy 学习手册(5)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Windows Update服务启动方法saas系统多租户数据隔离的实现(一)数据隔离方案下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

overload 函数或过程重载

//overload 函数或过程重载 重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同。实际上,编译器是通过检测参数来确定需要调用的例程。下面是从VCL的数学单元(Math Unit)中摘录的一系列函数:function Min (A,B: Integer): Integer; overload;function Min...

No module named "Crypto",如何安装Python三方模块Crypto

前两天公司公司老总让我研究怎么用企业微信第三方应用进行官网对接,完成URL回调验证问题。 具体如何进行Python 的Django网站与企业微信第三方应用进行回调验证的博客地址为:https://www.cnblogs.com/ws17345067708/p/10522472.html 这里讲讲,如何在win10下,安装一个非常坑爹的加密算法库,名字叫"C...

主流框架中DOMContentLoaded事件的实现(转)

也许还有朋友不太清楚DOMContentLoaded这个事件。简单的说,这个事件就是要在大多数情况下去替代window.onload事件,因为window.onload事件必须要等待页面所有元素的资源都下载完毕时才触发。这个事件实际是上w3c推荐的标准事件,是在DOM树建成的时候触发,因此要比onload事件快很多。ff, opera高版本已经支持了该事件...

v-model的实现原理

基础用法 v-model 本质上不过是语法糖,可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。v-model 会忽略所有表单元素的 ...

把微信小程序异步API转为Promise,简化异步编程

把微信小程序异步API转化为Promise。用Promise处理异步操作有多方便,谁用谁知道。 微信官方没有给出Promise API来处理异步操作,而官方API异步的又非常多,这使得多异步编程会层层回调,代码一复杂,回调起来就想砸电脑。 于是写了一个通用工具,把微信官方的异步API转化为Promise,方便处理(多)异步操作。 你可以这样用: 准备转化后...

JAVA中GC时finalize()方法是不是一定会被执行?

在回答上面问题之前,我们一定要了解JVM在进行垃圾回收时的机制,首先: 一、可达性算法  要知道对象什么时候死亡,我们需要先知道JVM的GC是如何判断对象是可以回收的。JAVA是通过可达性算法来来判断对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到G...