关于groovy:Y-分钟速成-Groovy

源代码下载: learngroovy-cn.groovy Groovy - Java 平台的动静语言,理解更多。 /* 装置: 1) 装置 GVM - http://gvmtool.net/ 2) 装置 Groovy: gvm install groovy 3) 启动 groovy 控制台,键入: groovyConsole*/// 双斜线开始的是单行正文/*像这样的是多行正文*/// Hello Worldprintln "Hello world!"/* 变量: 能够给变量赋值,以便稍后应用*/def x = 1println xx = new java.util.Date()println xx = -3.1499392println xx = falseprintln xx = "Groovy!"println x/* 汇合和映射*///创立一个空的列表def technologies = []/*** 往列表中减少一个元素 ***/// 和Java一样technologies.add("Grails")// 左移增加,返回该列表technologies << "Groovy"// 减少多个元素technologies.addAll(["Gradle","Griffon"])/*** 从列表中删除元素 ***/// 和Java一样technologies.remove("Griffon")// 减号也行technologies = technologies - 'Grails'/*** 遍历列表 ***/// 遍历列表中的元素technologies.each { println "Technology: $it"}technologies.eachWithIndex { it, i -> println "$i: $it"}/*** 查看列表内容 ***///判断列表是否蕴含某元素,返回booleancontained = technologies.contains( 'Groovy' )// 或contained = 'Groovy' in technologies// 查看多个元素technologies.containsAll(['Groovy','Grails'])/*** 列表排序 ***/// 排序列表(批改原列表)technologies.sort()// 要想不批改原列表,能够这样:sortedTechnologies = technologies.sort( false )/*** 列表操作 ***///替换列表元素Collections.replaceAll(technologies, 'Gradle', 'gradle')//打乱列表Collections.shuffle(technologies, new Random())//清空列表technologies.clear()//创立空的映射def devMap = [:]//增加值devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']devMap.put('lastName','Perez')//遍历映射元素devMap.each { println "$it.key: $it.value" }devMap.eachWithIndex { it, i -> println "$i: $it"}//判断映射是否蕴含某键assert devMap.containsKey('name')//判断映射是否蕴含某值assert devMap.containsValue('Roberto')//获得映射所有的键println devMap.keySet()//获得映射所有的值println devMap.values()/* Groovy Beans GroovyBeans 是 JavaBeans,但应用了更简略的语法 Groovy 被编译为字节码时,遵循下列规定。 * 如果一个名字申明时带有拜访修饰符(public, private, 或者 protected), 则会生成一个字段(field)。 * 名字申明时没有拜访修饰符,则会生成一个带有public getter和setter的 private字段,即属性(property)。 * 如果一个属性申明为final,则会创立一个final的private字段,但不会生成setter。 * 能够申明一个属性的同时定义本人的getter和setter。 * 能够申明具备雷同名字的属性和字段,该属性会应用该字段。 * 如果要定义private或protected属性,必须提供申明为private或protected的getter 和setter。 * 如果应用显式或隐式的 this(例如 this.foo, 或者 foo)拜访类的在编译时定义的属性, Groovy会间接拜访对应字段,而不是应用getter或者setter * 如果应用显式或隐式的 foo 拜访一个不存在的属性,Groovy会通过元类(meta class) 拜访它,这可能导致运行时谬误。*/class Foo { // 只读属性 final String name = "Roberto" // 只读属性,有public getter和protected setter String language protected void setLanguage(String language) { this.language = language } // 动静类型属性 def lastName}/* 逻辑分支和循环*///Groovy反对常见的if - else语法def x = 3if(x==1) { println "One"} else if(x==2) { println "Two"} else { println "X greater than Two"}//Groovy也反对三元运算符def y = 10def x = (y > 1) ? "worked" : "failed"assert x == "worked"//for循环//应用区间(range)遍历def x = 0for (i in 0 .. 30) { x += i}//遍历列表x = 0for( i in [5,3,2,1] ) { x += i}//遍历数组array = (0..20).toArray()x = 0for (i in array) { x += i}//遍历映射def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']x = ""for ( e in map ) { x += e.value x += " "}assert x.equals("Roberto Grails Groovy ")/* 运算符 在Groovy中以下罕用运算符反对重载: http://www.groovy-lang.org/operators.html#Operator-Overloading 实用的groovy运算符*///开展(spread)运算符:对聚合对象的所有元素施加操作def technologies = ['Groovy','Grails','Gradle']technologies*.toUpperCase() // 相当于 technologies.collect { it?.toUpperCase() }//平安导航(safe navigation)运算符:用来防止NullPointerExceptiondef user = User.get(1)def username = user?.username/* 闭包 Groovy闭包好比代码块或者办法指针,它是一段代码定义,能够当前执行。 更多信息见:http://www.groovy-lang.org/closures.html*///例子:def clos = { println "Hello World!" }println "Executing the Closure:"clos()//传参数给闭包def sum = { a, b -> println a+b }sum(2,4)//闭包能够援用参数列表以外的变量def x = 5def multiplyBy = { num -> num * x }println multiplyBy(10)// 只有一个参数的闭包能够省略参数的定义def clos = { print it }clos( "hi" )/* Groovy能够记忆闭包后果 [1][2][3]*/def cl = {a, b -> sleep(3000) // 模仿费时操作 a + b}mem = cl.memoize()def callClosure(a, b) { def start = System.currentTimeMillis() mem(a, b) println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs."}callClosure(1, 2)callClosure(1, 2)callClosure(2, 3)callClosure(2, 3)callClosure(3, 4)callClosure(3, 4)callClosure(1, 2)callClosure(2, 3)callClosure(3, 4)/* Expando Expando类是一种动静bean类,能够给它的实例增加属性和增加闭包作为办法 http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html*/ def user = new Expando(name:"Roberto") assert 'Roberto' == user.name user.lastName = 'Pérez' assert 'Pérez' == user.lastName user.showInfo = { out -> out << "Name: $name" out << ", Last name: $lastName" } def sw = new StringWriter() println user.showInfo(sw)/* 元编程(MOP)*///应用ExpandoMetaClass减少行为String.metaClass.testAdd = { println "we added this"}String x = "test"x?.testAdd()//拦挡办法调用class Test implements GroovyInterceptable { def sum(Integer x, Integer y) { x + y } def invokeMethod(String name, args) { System.out.println "Invoke method $name with args: $args" }}def test = new Test()test?.sum(2,3)test?.multiply(2,3)//Groovy反对propertyMissing,来解决属性解析尝试class Foo { def propertyMissing(String name) { name }}def f = new Foo()assertEquals "boo", f.boo/* 类型检查和动态编译 Groovy天生是并将永远是一门动静语言,但也反对类型检查和动态编译 更多: http://www.infoq.com/articles/new-groovy-20*///类型查看import groovy.transform.TypeCheckedvoid testMethod() {}@TypeCheckedvoid test() { testMeethod() def name = "Roberto" println naameee}//另一例子import groovy.transform.TypeChecked@TypeCheckedInteger test() { Integer num = "1" Integer[] numbers = [1,2,3,4] Date date = numbers[1] return "Test"}//动态编译例子import groovy.transform.CompileStatic@CompileStaticint sum(int x, int y) { x + y}assert sum(2,5) == 7进阶资源Groovy 文档 ...

November 28, 2022 · 3 min · jiezi

关于groovy:初探Groovy

初探Groovy简介Groovy 是一门 JVM 语言,因而只有有JVM即可执行。而且Groovy与Java能够互相调用,亲测丝滑。 丝滑到什么水平呢?就是在Java我的项目我的项目中能够同时并存.java和.groovy文件,能够互相调用。 Groovy 是动静语言,引入很多有意思的个性。如果将Java比喻为楷书,则Groovy是行书,开发效率很高。而且Groovy JDK中蕴含很多实用工具,开发舒服。 指标Groovy is an optionally typed, dynamic language for the Java platform with many features that are inspired by languages like Python, Ruby, and Smalltalk, making them available to Java developers using a Java-like syntax. Unlike other alternative languages, it is designed as a companion, not a replacement for Java. —— Groovy In Action (page 44) 咱们的指标不是要替换Java,而是成为Java的搭档。将一些用Java解决起来很简单的工序,交给Groovy解决。 运行形式简略而言有两种形式: compile:编译期编译为 .class文件runtime:作为脚本由GroovyShell动静执行 毕竟是动静语言,出于性能思考,倡议外围代码、底层代码,用Java。业务逻辑、须要疾速变动的逻辑,尝试用Groovy。 ...

September 9, 2022 · 2 min · jiezi

关于groovy:Groovy-Java-混合编程方案GMaven

Groovy + Java 混合编程计划:GMavenHava a look先看成果。在我的项目中轻易创立一个 SayHiUtil.groovy,而后在main外面增加个执行打印一下 package com.cmb.lr20.zxb.dialog.utilsclass SayHIUtil { static def sayHi() { println "Hi groovy" }}public class DialogApplication { public static void main(String[] args) { SayHIUtil.sayHi(); SpringApplication.run(DialogApplication.class, args); }} DO IT!应用GMavenPlus,只需加个 plugin 和 dependency 即可: <dependencies> <!-- Groovy --> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy</artifactId> <version>3.0.9</version> </dependency> </dependencies><build> <plugins> <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> <version>1.13.1</version> <executions> <execution> <goals> <goal>addSources</goal> <goal>addTestSources</goal> <goal>generateStubs</goal> <goal>compile</goal> <goal>generateTestStubs</goal> <goal>compileTests</goal> <goal>removeStubs</goal> <goal>removeTestStubs</goal> </goals> </execution> </executions> </plugin> <plugin> <!-- if including source jars, use the no-fork goals otherwise both the Groovy sources and Java stub sources will get included in your jar --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <!-- source plugin \> = 2.1 is required to use the no-fork goals --> <version>3.2.1</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar-no-fork</goal> <goal>test-jar-no-fork</goal> </goals> </execution> </executions> </plugin> </plugins></build>

September 7, 2022 · 1 min · jiezi

关于groovy:有道词典Android客户端包体积优化之路

1 背景有道词典从挪动互联网之初就凭借玲珑疾速、功能强大的印象让用户爱上翻译查词,爱上学习。随着业务一直地迭代以及性能不断完善,有道词典不再是单纯的查词软件,而是变成了用户的综合学习平台。咱们摸索过社区、问答、直播、信息流等业务,目前也承载着音频、视频、课程、背单词、写作批改等等的性能。词典曾经倒退成为一个综合性的学习平台,玲珑疾速的初心依然指引着咱们一直进行启动速度以及包体积优化。 通过了一直的性能优化,目前咱们的冷启动工夫曾经能维持在业界规范程度3s以内。咱们近一个季度次要的性能优化工作集中在安装包体积优化下面。通过一系列的致力,咱们包体积缩小了23.7%,安装包体积从177MB缩小到135MB,整体少了42MB。 以下具体介绍咱们的剖析以及实现细节。 2 剖析介绍下包体积蕴含的内容以及优化办法概述 个别的APK安装包蕴含了以下一些目录和资源: META-INF/ 签名文件 assets/ 程序应用的辅助资源文件 res/ 没有编译进入resources.arsc 资源文件,个别是图片 lib/ 依赖的不同native平台的库文件 resource.arsc 编译之后的文案、色值、大小、主题等资源索引 classes.dex 编译后的代码 AndroidMenifest.xml 利用的名称、版本、拜访权限和援用的库文件信息 能够看出占比拟大的局部次要是别离是assets/、lib/、res/、classes.dex以及resources.arsc,大略对应的就是资源、库文件、代码以及资源索引。咱们次要的优化思路如下(其中蓝色框局部为目前曾经解决局部): 3 技术实现细节3.1 图片压缩在APK打包的过程中,aapt 工具会默认对图片进行无损压缩,不过默认的压缩并不能达到一个很好的压缩成果,通过了比照webp以及tinypng的压缩成果,咱们最终抉择了应用tinypng对图片进行压缩。并且咱们编写了编译工具,对图片进行自动化压缩。 有损webp > tinypng > 无损webp 比方这张启动图,原大小724KB,压到75%左右的品质只有23.7KB。成果上有一点点差别,但能够承受。那么咱们是否能够把全副png图压成有损webp呢?答案是否定的,能够看看上面的例子: 压缩前: 压缩后: 能够看到,雷同的压缩品质下(75%),这个图就变得非常含糊,哪怕抉择到了99%的压缩品质,突变区域仍然会呈现一些没有天然过渡的条纹。 对于上述的状况,用tinypng计划更好 原图:643KB, tinypng: 152KB, webp:339KB 综上,对于有损webp,无奈找到一个固定的压缩品质来适配所有场景。有损webp有些时候甚至比tinypng还大,但显示品质更差。 咱们最后应用的抖音的McImage插件对图片进行解决,不过这个计划存在一些显著的问题: 计划采纳有损webp,有损webp无奈定一个通用的压缩品质适应所有场景。每次打包都要对所有图进行压缩,重大影响迭代效率。打包机要40分钟,且常常OOM。没有对assets目录的图片进行解决。针对以上问题,咱们本人开发了一套应用tinypng的自动化图片压缩工具,做出以下调整: 1.对于大图png,用手工压成有损webp。收益大,且危险可控。2.对于非大图,开发了一个image-optimization插件进行压缩。该插件计划为: · png转tinypng。尽管是有损的,但从抽样来看,肉眼齐全看不到显著变动。 · 对assets进行解决。assets内有前端png图,转tinypng不转webp的益处是不须要独自改html、js等文件,且对低版本零碎兼容性更敌对。flutter相干我的项目的flutter_assets图片比拟大且没留神压缩。插件对立解决能够不须要关上flutter工程独自优化、从新打包。 · 对于已压缩的图片,做缓存解决,不须要从新压缩,打包的时候动静替换。压缩缓存追随词典工程提交到gitlab对立治理。 以下是咱们图片自动化压缩插件解决的流程图: 这里压缩图是否可用判断,次要是大小判断,如果压出来比原图大,那么将舍弃。比方crunchPng压缩就存在这种状况 附加1:因为曾经用了tinypng对立压缩,那么google官网自带的crunchPng倡议敞开,否则打包速度变慢,而且优化好的图片也可能又变大,退出这行即可: buildTypes.all {\ isCrunchPngs = false\}附加2:无损webp和tinypng比照 如图所示,全量换tinypng比全量换webp(蕴含assets)少7.7MB。如果思考到assets内的14.7MB其实是不能简略换webp的,差距会更大。 附加3:tinypng曾经是最好的计划吗? 参考另一个ImageOptim工具,它联合OptiPNG, PNGCrush, AdvanceComp, PNGOUT, Jpegoptim + Jpegtran, 和 Gifsicle 等几个工具提供最好的优化成果,而且是简直无损的。对于小局部图片ImageOptim压出来小,看起来没有差异。不过压缩速度十分慢。 ...

April 21, 2022 · 2 min · jiezi