GROOVY预览

Stella981
• 阅读 515

1.Groovy 中的闭包

Java的一些不足可以通过使用groovy的闭包很好的解决,通过下面这个例子来看看使用闭包的优势:
在Java中遍历一个集合的方法是使用迭代,就像下面这样:

def acoll = ["Groovy", "Java", "Ruby"] for(Iterator iter = acoll.iterator(); iter.hasNext();){
 println iter.next()
}

实际上在 for 循环中并不需要类型声明,因为 Groovy 已经将迭代转变为任何集合的直接成员。在这个示例中,不必获取 Iterator 实例并直接操纵它,可以直接在集合上迭代。而且,通常放在循环构造内的行为(例如 for 循环体中 println)接下来要放在闭包内。在深入之前,先看看如何执行这步操作。

对于上面的代码,可以用更简洁的方式对集合进行迭代,如下所示:

def acoll = ["Groovy", "Java", "Ruby"]
        
acoll.each{
 println it
}

请注意,each 直接在 acoll 实例内调用,而 acoll 实例的类型是 ArrayList。在 each 调用之后,引入了一种新的语法 — {,然后是一些代码,然后是 }。由 {} 包围起来的代码块就是闭包。

闭包是可执行的代码块。它们不需要名称,可以在定义之后执行。所以,在上面的示例中,包含输出 it(后面将简单解释 it)的行为的无名闭包将会在 acoll 集合类型中的每个值上被调用。
在较高层面上,{} 中的代码会执行三次,从而生成如图所示的输出。

Groovy
Java
Ruby

2声明闭包

  迄今为止,我们已经使用了闭包的简单语法:在一个方法调用的后面,放置闭包代码在一对花括号里,闭包的参数和代码通过(->)进行分隔。

  2.1简单的声明方式

  下图中显示了闭包语法的简单方式和一个新的特性,当只有一个参数传递的时候,这个参数是可选的,魔术变量it代替了声明

GROOVY预览

log='' (1..10).each{counter -> log += counter }
println log //12345678910  log='' (1..10).each{log += it }
println log //12345678910

GROOVY预览

  上面两个闭包声明是等价的,注意,不像counter,魔术变量it是不需要声明的。

  2.2 使用赋值的方式声明闭包

  第二种声明闭包的方式是直接将它赋值给一个变量

def printer={ line -> println line}

闭包声明在花括号中,并且赋给了printer变量

通过方法的返回值也是一种闭包的声明方式

def Closure getPrinter(){ return {line -> println line}
}

花括号指明构建了一个新的闭包对象,这个对象通过方法的调用返回

  2.3引用一个方法作为闭包

  第三种声明闭包的方式是重用已有的声明:一个方法。方法有一个方法体,可选的返回值,能够接受参数,并且能够被调用,于grooovy的闭包的相似性显而易见,因此groovy可以重用你已经在方法中存在的代码作为一个闭包,引用一个方法作为闭包使用reference.&操作符, reference是闭包调用时使用的对象实例,正如一个一般的方法调用使用reference.someMethod().  

GROOVY预览

上图显示了闭包的调用方法。

下面代码演示了方法闭包的使用

GROOVY预览

class MethodClosureSample{ int limit
    
    MethodClosureSample(int limit){ this.limit = limit
    } boolean validate(String value){ return value.length() <= limit
    }
}

MethodClosureSample first = new MethodClosureSample(6)
MethodClosureSample second = new MethodClosureSample(4)

def firstClosure = first.&validate; //方法作为闭包  def words=['Hello','Synvata','I','Love','you']

println words.findAll(firstClosure) //[Hello, I, Love, you] println words.findAll(second.&validate) //[I, Love, you]

GROOVY预览

3 比较

下面展示了创建和使用闭包的所有方式:使用简单声明、赋值变量和方法闭包

GROOVY预览

map=['a':1,'b':2,'c':3] /*直接把闭包作为参数传递,这是常用的方式*/ map.each{key,value -> map[key] = value * 2 }
println map //[a:2, b:4, c:6] /*将闭包对象赋值给变量doubler*/ doubler={key,value -> map[key] = value * 2 }
map.each(doubler)
println map //[a:4, b:8, c:12] /*声明一个普通的方法*/ def doubleMethod(entry){
   map[entry.key]=entry.value * 2 } /*reference.&操作符引用方法作为一个闭包*/ doubler=this.&doubleMethod
println doubler //org.codehaus.groovy.runtime.MethodClosure@3fb547 map.each(doubler)
println map //[a:8, b:16, c:24]

GROOVY预览

 4 调用闭包

假设有一个引用x指向一个闭包,我们能通过x.call()来调用闭包,或者简单的x()

def col={println 'Hello, Groovy'}
col(); //Hello, Groovy col.call() //Hello, Groovy

现在,我们来试试更复杂的一些东西,从一个方法的内部调用闭包

GROOVY预览

def benchmark(repeat,Closure worker){
    start=System.currentTimeMillis()
    repeat.times{worker(it)}
    stop=System.currentTimeMillis() return stop-start
}

slow=benchmark(1000){ (int)it / 2 }
fast=benchmark(1000){ it.intdiv(2) }
println slow
println fast

GROOVY预览

在benchmark中我们把闭包作为最后一个参数,这样在调用该方法的时候就可以使用闭包的简单语法声明benchmark(){Closure}。方法参数中Closure声明了闭包的类型,该声明是可选的。repeat.times{worker(it)}根据repeat参数重复的调用闭包,并把当前重复的次数传入闭包

因为不想编写文档,就COPY了一下博客园的一篇博文,不敢说是自己写的,说明出处:

http://www.cnblogs.com/jyan/archive/2012/06/01/2529898.html

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
御弟哥哥 御弟哥哥
3年前
Groovy中的类
Groovy中的类迄今为止,您已经用Groovy输出了许多次“HelloWorld”,已经操作了集合,用闭包在集合上迭代,也定义了您自己的闭包。做所有这些工作时,甚至还没有讨论那个对Java开发人员来说至关重要的概念—类。当然,您已经在这个教程中使用过类了:您编写的最后几个示例就是在不同类的main()方法中。而且,您已经知道,在
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这