Groovy闭包
程序员文章站
2022-06-19 14:57:35
文章目录1、优雅介绍闭包2、闭包场景2.1、使用迭代器(iterators)2.2、 使用一个协议处理资源3、声明闭包3.1、简单申明3.2、为声明赋值3.3、闭包对应多个方法3.4、 比较可选值4、使用闭包4.1、调用闭包4.2、更多闭包能力5、理解闭包域5.1、简单变量域5.2、观察闭包域5.3、经典累加测试6、闭门返回值7、支持设计模式7.1、观察者模式8、总结1、优雅介绍闭包一段代码块作为一个对象看待it作为提供闭包的默认名称2、闭包场景2.1、使用迭代器(iterators)//...
文章目录
1、优雅介绍闭包
- 一段代码块作为一个对象看待
- it作为提供闭包的默认名称
2、闭包场景
2.1、使用迭代器(iterators)
// java 5
for (ItemType item : list){
// 具体逻辑
}
// groovy 对象
list.each{ item ->
// 具体逻辑
}
// java 8 with lambda
list.stream().forEach((item) -> {
// 具体逻辑
})
// java 8 groovy 闭包
list.stream().forEach{println it}
2.2、 使用一个协议处理资源
-
new File('myfile.txt').eachLine{println it} // handler //java a @FuncionalInterface in java 8 interface ResourceUser{ void use(Resource resource) } // 使用 resourceHandler.handle(new ResourceUser(){ public void use (Resource resource){ resource.doSomething() } }); // groovy resourceHandler.handle{ resource -> resource.doSomething()}
3、声明闭包
3.1、简单申明
-
/** * 简单闭包申明 * @author liangchen* @date 2020/11/4 */ class SimpleDeclarationDemo { static void main(String[] args) { // 自定义参数名 counter def log = "" (1..10).each { counter -> log += counter} assert log == '12345678910' // it就是默认参数名称 log = '' (1..10).each { log += it } assert log == '12345678910' } }
3.2、为声明赋值
-
/** * 闭包定义 * @author liangchen* @date 2020/11/4 */ class AssignmentClosure { static void main(String[] args) { AssignmentClosure assignmentClosure = new AssignmentClosure() def t= 1111 assignmentClosure.printers.call(t) } // 闭包定义方式一 def printers = { line -> println line} // 方式二 Closure getPrinter(){ return { line -> println line} } }
3.3、闭包对应多个方法
-
闭包也可以用于查询 过滤条件
-
/** * @author liangchen* @date 2020/11/4 */ class MultiMethodSample { static void main(String[] args) { SizeFilter filter1 = new SizeFilter(limit: 6) SizeFilter filter2 = new SizeFilter(limit: 5) // 方法闭包赋值 Closure sizeUpTo6 = filter1.&sizeUpTo def words = ['long string', 'medium', 'short', 'tiny'] assert 'medium' == words.find(sizeUpTo6) assert 'short' == words.find(filter2.&sizeUpTo) //========= // 根据不同参数找到不同闭包对应方法 MultiMethodSample methodSample = new MultiMethodSample() Closure multi = methodSample.&mysteryMethod assert 10 == multi('string arg') assert 3 == multi(['list','of','values']) assert 14 == multi(6, 8) } int mysteryMethod (String value){ return value.length(); } int mysteryMethod(List list) { return list.size(); } int mysteryMethod(int x, int y) { return x + y } } /** * 大小过滤 */ class SizeFilter { Integer limit boolean sizeUpTo(String value) { return value.size() <= limit } }
-
3.4、 比较可选值
4、使用闭包
4.1、调用闭包
-
有点类似
-
/** * 闭包定义规则,比如做一下,四则运算 * @author liangchen* @date 2020/11/4 */ class CallingClosureDemo { static void main(String[] args) { def adder = { x, y -> return x + y } assert adder(4,3) == 7 assert adder.call(2, 6) == 8 def slow = benchmark(10000) { (int) it / 2 } def fast = benchmark(10000) { it.intdiv(2) } assert fast * 2 < slow def plus = calculate(1, 2) { x, y -> x + y } assert plus == 3 def multi = calculate(1, 2) { x, y -> x * y } assert multi == 2 } def static benchmark(int repeat, Closure worker){ def start = System.nanoTime() repeat.times {worker(it)} def stop = System.nanoTime() return stop - start } def static calculate(int num1, int num2, Closure worker) { worker(num1, num2) } }
4.2、更多闭包能力
-
/** * 更多闭包特性 和 curry * @author liangchen* @date 2020/11/5 */ class MoreClosureDemo { static void main(String[] args) { //判断closure 参数是1 assert numParams {one ->} == 1 //判断closure 参数数量是2 assert numParams { one, two -> } == 2 // 判断参数类型 assert paramTypes { String s -> } == [String] assert paramTypes {Number n, Date d ->} == [Number, Date] // currying 填充未知数 def mult = { x, y, z -> return x * y * z } // {x,y,z -> return 2 * y * z} def twoTimes = mult.curry(2) // {x,y,z -> return 2 * 3 * z} def threeTimes = twoTimes.curry(3) // {x,y,z -> return 2 * 3 * 60} assert threeTimes(10) == 60 // 将参数归纳一下, 有点类似定义抽象问题 def configurator = { format, filter, line -> filter(line) ? format(line) : null } def appender = {config, append ,line -> def out = config(line) if(out) append(out) } def dateFormatter = { line -> "${new Date()} : $line" } def debugFilter = { line -> line.contains('debug') } def consoleAppender = {line -> println line} def myConf = configurator.curry(dateFormatter, debugFilter) def myLog = appender.curry(myConf, consoleAppender) myLog("here is some debug message") myLog("this will not be printed") // 合并组合closure // currying 填充未知数 mult = { x, y -> return x * y } // {x,y,z -> return 2 * y * z} twoTimes = mult.curry(2) def fourTimes = twoTimes >> twoTimes def eightTimes = twoTimes << fourTimes assert eightTimes(1) == twoTimes(fourTimes(1)) // 内存化 提高访问速度 def fib fib = { it < 2 ? 1 : fib(it - 1) + fib(it - 2) } fib = fib.memoize() assert fib(40) == 165_580_141 // trampoline 蹦床 防止递归栈溢出 def last last = { it.size() == 1 ? it.head() : last.trampoline(it.tail()) } last = last.trampoline() assert last(0..10_000) == 10_000 } def static numParams(Closure closure) { closure.getMaximumNumberOfParameters() } def static paramTypes(Closure closure) { closure.getParameterTypes() } }
5、理解闭包域
- 那个变量可以获得
- 什么时候或怎么绑定到这值
- 你怎么样控制这个作用域
5.1、简单变量域
-
/** * 闭包的作用域 * @author liangchen* @date 2020/11/5 */ class ClosureScopeDemo { static void main(String[] args) { def x = 0 10.times { x++ } assert x == 10 } }
5.2、观察闭包域
-
/** * Closure域 * @author liangchen* @date 2020/11/6 */ class InvestigateClosureScope { static void main(String[] args) { Mother julia = new Mother() def closure = julia.birth('param') // 获取closure上下文 def context = closure.call() assert context[0] == julia assert context[1, 2] == ['prop', 'method'] assert context[3, 4] == ['local', 'param'] // 对象 assert closure.thisObject == julia assert closure.owner == julia // 代理 assert closure.delegate == julia assert closure.resolveStrategy == Closure.OWNER_FIRST def map = [:] // map 进行代理 map.with { a = 1 b = 2 } assert map == [a: 1, b: 2] } } class Mother { def prop = 'prop' def method(){ 'method' } Closure birth(param){ def local = 'local' def closure = { [this, prop, method(), local, param] } return closure } }
5.3、经典累加测试
-
累加器
-
/** * * groovy 累加器 * @author liangchen* @date 2020/11/6 */ class AccumulatorTest { static void main(String[] args) { def accumulator = foo(1) // 1+2 ==3 assert accumulator(2) == 3 // 3+1 ==4 assert accumulator(1) == 4 // 4+1==5 assert accumulator(1) == 5 } static def foo(n) { return { n += it } } }
6、闭门返回值
-
/** * closure 返回值 * @author liangchen* @date 2020/11/6 */ class ClosureReturnDemo { static void main(String[] args) { // 不需要return def doubled = [1,2,3].collect{it * 2} assert doubled == [2,4,6] // return 关键字 doubled = [1,2,3].collect { return it * 2 } assert doubled == [2,4,6] // 偶数 * 2, 奇数直接返回 def odd= [1,2,3].collect { if(it % 2 ==0) return it * 2 return it } assert odd == [1,4,3] } }
7、支持设计模式
7.1、观察者模式
-
/** * 观察者模式 * @author liangchen* @date 2020/11/6 */ class VisitorPatternDemo { static void main(String[] args) { def picture = new Drawing(shapes: [new Square(width: 1), new Circle(radius: 1)]) def total = 0 // 累加的Closure picture.accept {total += it.area()} println "The shapes in this drawing cover an area of $total units." println "The individual contributions are: " picture.accept {println it.class.name + ":" + it.area()} } } class Drawing { List shapes def accept(Closure yield){ shapes.each {it.accept(yield)} } } class Shape { def accept(Closure yield){ yield(this) } } class Square extends Shape{ def width def area() { width**2 } } class Circle extends Shape{ def radius def area() { Math.PI * radius**2 } }
8、总结
- 一段代码也是算是一个Closure
- 有点类似java lambda风格
本文地址:https://blog.csdn.net/m0_37355951/article/details/110244178
上一篇: 资深大厂架构师JAVA高级开发+性能调优+缓存实战
下一篇: Springboot设置接口超时配置