groovy常用语法及实战
groovy语言简介
- 一种基于JVM的敏捷开发语言,作为编程语言可编译成java字节码,也可以作为脚本语言解释执行。
- 结合了Python、Ruby和Smalltalk的许多强大的特性
- 支持面向对象编程也支持面向过程编程
- 支持动态类型,闭包等语言特性
- 无缝集成所有已经存在的java类库
groovy环境搭建
参考官网groovy环境搭建
groovy的hello world
在groovy语言中,如下两种写法效果完全相同
版本1:
class HelloGroovy {public static void main(String[] args) {System.out.println("hello groovy!");} }
版本2:
print "hello groovy"
版本2看起来是脚本,其实是编译器帮我们变成了class,版本2脚本对应的class反编译为如下代码:
import groovy.lang.Binding; import groovy.lang.Script; import org.codehaus.groovy.runtime.InvokerHelper; public class HelloGroovy extends Script {public HelloGroovy() {}public HelloGroovy(Binding context) {super(context);}public static void main(String... args) {InvokerHelper.class.invoke<invokedynamic>(InvokerHelper.class, HelloGroovy.class, args);}public Object run() {return this.invoke<invokedynamic>(this, "hello groovy");} }
我们直观感受一个是编译语言,一个是脚本语言,但其实最后都是编译执行的。
groovy基础语法
变量
变量类型:全部为对象类型,不存在基本类型,基本类型的定义都会被转化为对象类型。
package variable int x = 10 println x.class double y = 3.14 println y.class
输出为:
class java.lang.Integer class java.lang.Double
变量定义:强类型和弱类型def定义
def x_1 = 3.1415 println x_1.class
def
定义时,会根据值的类型将变量转化为对应类型,重新赋值为其他数据类型的值,则变量类型也会变为其他数据类型
建议:内部使用的变量建议使用def
定义,而提供给外部程序使用的变量,则建议使用强类型
字符串
String
和GString
字符串使用单引号、双引号和三个单引号定义都等同为String
,区别:
- 单引号没有格式,格式需要转义,比如换行需要拼接;三个单引号可以直接指定格式
- 单引号不能引入扩展表达式,双引号可以在字符串中引入扩展表达式。如果双引号存在扩展表达式,类型则为
GString
//def name = 'a single \'a\'string' //println name.classdef thupleName = '''\ line one line two line three ''' //println thupleNamedef doubleName = "this a common String" //println doubleName.classdef name = "Qndroid" def sayHello = "Hello: ${name}" //println sayHello //println sayHello.classdef sum = "the sum of 2 and 3 equals ${2 + 3}" //可扩展做任意的表达式 //println sum
String方法来源:
java.lang.String
,常用java类型,比较熟悉了
DefaultGroovyMethods
,groovy所有类型都有的方法
StringGroovyMethods
,继承DefaultGroovyMethods
,有普通类型的参数和闭包类型的参数
package org.codehaus.groovy.runtime; ... public class StringGroovyMethods extends DefaultGroovyMethodsSupport { ...
groovy新增的部分string方法如下:
/* ==================字符串的方法=================== */ def str = "groovy Hello" //println str.center(8) //println str.padLeft(8, 'a') def str2 = 'Hello' //println str > str2 //println str[0] //println str[0..1] //println str - str2//println str.reverse() //println str.capitalize()
逻辑控制
//对范围的for循环 def sum = 0 for (i in 0..9) {sum += i } //println sum sum = 0 /*** 对List的循环*/ for (i in [1, 2, 3, 4, 5, 6, 7, 8, 9]) {sum += i } /*** 对Map进行循环*/ for (i in ['lili': 1, 'luck': 2, 'xiaoming': 3]) {sum += i.value }
方法调用
方法如果只有一个参数,可以省略()
groovy闭包
闭包定义、调用和返回值
闭包就是一段代码块,代码块用{ }
表示
def clouser = { println "hello groovy!" } //闭包调用 //clouser.call() clouser()
闭包普通参数和隐式参数
->之前就是参数部分,可以为空(没有参数)
//普通参数 def clouser = { String name -> println "hello ${name}!" } //闭包调用 //clouser.call()def name = 'groovy!' clouser(name)//多个参数 def clouser = {String name, int age -> println "hello ${name}, My age is ${age}" } def name = 'groovy!' clouser(name,4)//默认隐式参数 it def clouser = { println "hello ${it}"} def name = 'groovy!' clouser(name)
闭包的返回值
如果有return
语句,则返回对应值,如果没有return
语句,则返回null
。
闭包的用法
与基本类型的结合,闭包参数需要查看源码,看需要传入的参数
int x = fab(5) println x //用来求指点number的阶乘 int fab(int number) {int result = 11.upto(number, {num -> result *= num})return result } //结果为120int cal(int number) {int result = 0number.times {num -> result += num}return result }
upto
源码
public static void upto(Number self, Number to, @ClosureParams(FirstParam.class) Closure closure) {int self1 = self.intValue();int to1 = to.intValue();if (self1 <= to1) {for (int i = self1; i <= to1; i++) {closure.call(i);}} elsethrow new GroovyRuntimeException("The argument (" + to +") to upto() cannot be less than the value (" + self + ") it's called on."); }
与String结合
String str = 'the 2 and 3 is 5' //each的遍历,返回值为本身 str.each {String temp -> print temp } //find 来查找符合条件的第一个 str.find {String s-> s.isNumber() }
find
源码
public static Object find(Object self, Closure closure) {BooleanClosureWrapper bcw = new BooleanClosureWrapper(closure);for (Iterator iter = InvokerHelper.asIterator(self); iter.hasNext();) {Object value = iter.next();if (bcw.call(value)) {return value;}}return null; }
与数据结构结合
与文件等结合
闭包进阶
闭包关键变量this
闭包关键变量owner
闭包关键变量delegate
/*** 闭包的三个重要变量:this,owner,delegate*/ def scriptClouser = {println "scriptClouser this:" + this //闭包定义处的类println "scriptClouser owner:" + owner //闭包定义处的类或者对象println "scriptClouser delegate:" + delegate //任意对象,默认为owner一致 } scriptClouser.call()//this为闭包定义处的类,//定义了一个内部类,在脚本类中 class Person {def static classClouser = {println "classClouser this:" + thisprintln "classClouser owner:" + ownerprintln "classClouser delegate:" + delegate}def static say() {def classClouser = {println "methodClassClouser this:" + thisprintln "methodClassClouser owner:" + owner println "methodClassClouser delegate:" + delegate}classClouser.call()} } Person.classClouser.call() Person.say()//闭包中定义一个闭包 def nestClouser = {def innerClouser = {println "innerClouser this:" + thisprintln "innerClouser owner:" + owner println "innerClouser delegate:" + delegate}innerClouser.call() } nestClouser.call()
闭包的委托策略
/*** 闭包的委托策略*/ class Student {String namedef pretty = { "My name is ${name}"}String toString() {pretty.call()} } class Teacher {String name } def stu = new Student('Sarash') def tea = new Teacher('Ondroid') stu.pretty.delegate = tea stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST println stu.toString()
常见数据结构使用
列表的定义
//def list = new ArrayList() //java的定义方式 def list = [1, 2, 3, 4, 5] println list.class println list.size() def array = [1, 2, 3, 4, 5] as int[] int[] array2 = [1, 2, 3, 4, 5]
列表的操作:原理为操作ArrayList
映射map
的定义
//def map = new HashMap() def colors = [red : 'ff0000',green: '00ff00',blue : '0000ff'] //索引方式 //println colors['red'] //println colors.red colors.blue //添加元素 //colors.yellow = 'ffff00' colors.complex = [a: 1, b: 2] //println colors.getClass()
范围range
的定义和使用
def range = 1..10 //println range[0] //println range.contains(10) println range.from println range.to//遍历 range.each {// println it }for (i in range) {// println i }def result = getGrade(75) println resultdef getGrade(Number number) {def resultswitch (number) {case 0..<60:result = '不及格'breakcase 60..<70:result = '及格'breakcase 70..<80:result = '良好'breakcase 80..100:result = '优秀'break}return result }
面向对象特性
类、接口等的定义和使用
类:
- groovy中默认都是public
- 无论你是直接还是调用get/set,最终都是调用get/set
接口:
接口中不许定义非public的方法
Trait:
和接口一样,唯一不同是可以有默认实现
元编程
方法寻找流程
- 类中是否有此方法
MetaClass
中是否有此方法- 是否重写了
methodMissing()
- 是否重写了
InvokeMathod()
Throw MissingMethodException
为类动态的添加一个属性
Person.metaClass.sex = 'male'
为类动态的添加方法
Person.metaClass.nameUpperCase = { -> sex.toUpperCase()}
为类动态的添加静态方法
Person.metaClass.static.createPerson = {}
高级用法实战
json文件处理及json,model互转
代码样例:
import groovy.json.JsonOutput import groovy.json.JsonSlurper import objectorention.Person//def json = JsonOutput.toJson(list) def reponse =getNetworkData('http://xxx.json')println reponse.data.head.namedef getNetworkData(String url) {//发送http请求---完全是使用java库def connection = new URL(url).openConnection()connection.setRequestMethod('GET')connection.connect()def response = connection.content.text//将json转化为实体对象def jsonSluper = new JsonSlurper()return jsonSluper.parseText(response) }
xml文件读取
代码样例:
import groovy.xml.MarkupBuilderfinal String xml = '''<response version-api="2.0"><value><books id="1" classification="android"><book available="20" id="1"><title>疯狂Android讲义</title><author id="1">李刚</author></book><book available="14" id="2"><title>第一行代码</title><author id="2">郭林</author></book><book available="13" id="3"><title>Android开发艺术探索</title><author id="3">任玉刚</author></book><book available="5" id="4"><title>Android源码设计模式</title><author id="4">何红辉</author></book></books><books id="2" classification="web"><book available="10" id="1"><title>Vue从入门到精通</title><author id="4">李刚</author></book></books></value></response> '''//开始解析此xml数据 def xmlSluper = new XmlSlurper() def response = xmlSluper.parseText(xml)//println response.value.books[0].book[0].title.text() //println response.value.books[0].book[0].author.text() //println response.value.books[1].book[0].@availabledef list = [] response.value.books.each { books ->//下面开始对书结点进行遍历books.book.each { book ->def author = book.author.text()if (author.equals('李刚')) {list.add(book.title.text())}} } //println list.toListString()//深度遍历xml数据 def titles = response.depthFirst().findAll { book ->return book.author.text() == '李刚' ? true : false } //println titles.toListString()//广度遍历xml数据 def name = response.value.books.children().findAll { node ->node.name() == 'book' && node.@id == '2' }.collect { node ->return node.title.text() }//println name
普通文件的读写
java文件处理
- 节点流:
InputStream
,OutputStream
及其子类 - 处理流:
Reader
,Writer
及其子类
所有java对文件的处理类,groovy都可以使用
groovy扩展了许多更加快捷和强大的方法
代码示范:
def file = new File(pathname:'../../test.txt') file.eachline { line ->println line }def text = file.getText() println textdef result = file.readLines()//读取文件部分内容 def reader = file.withReader { reader ->char[] buffer = new char[100]reader.read(buffer)return buffer } println reader def copy(String sourcePath, String destationPath) {try {//首先创建目标文件def desFile = new File(destationPath)if (!desFile.exists()) {desFile.createNewFile()}//开始copynew File(sourcePath).withReader { reader ->def lines = reader.readLines()desFile.withWriter { writer ->lines.each { line ->writer.append(line + "\r\n")}}}return true} catch (Exception e) {e.printStackTrace()}return false }
groovy与java对比
- 没有java那么多的限制
- 对java的功能进行了极大的扩展
- 既可以编写应用,也可以编写脚本
语法上区别:
- Groovy 语句可以不用分号结尾
- 定义变量的时候可以不指定其类型、Groovy 中函数的返回值也可以是无类型的
- 最后一行代码的执行结果就是函数的返回值
- 如果指定了函数返回类型,则可不必加 def 关键字来定义函数
- Groovy中函数调用的时候还可以不加括号
- 闭包是一段代码,所以需要用花括号括起来
- -> 箭头前面是参数定义,箭头后面是代码
- Groovy 中,当函数的最后一个参数是闭包的话,可以省略圆括号或闭包放在后面
- 如果发送的实参的个数多于方法的形参个数,而且多出的实参是名值对,那么Groovy会假设方法的第一个形参是一个Map,然后将实参列表中的所有名值对组织到一起,作为第一个形参的值,之后,再将剩下的实参按照给出的顺序赋给其他的形参,就和我们输出的结果一样。
转载于:https://www.cnblogs.com/yufecheng/p/11302777.html
groovy常用语法及实战相关推荐
- SQL Server数据库学习总结及T-SQL语法使用实战
SQL Server数据库及T-SQL实战 声明 名词解释 SQL Server数据库 安装sql server 数据库中的三种完整性 SQL Server数据库基本操作 创建数据库 指定多个数据库文 ...
- C语言代码示范与讲解+C语言编程规范及基础语法+编程实战
上一篇文章:C语言程序设计概述+C语言简介+算法概述 C语言代码示范与讲解+C语言编程规范及基础语法+编程实战 一:代码示范集加讲解 1.C语言第一个代码:打印"This is the fi ...
- R语言switch语句语法、实战:Switch语句用来处理嵌套的if else处理起来比较困难或者麻烦的条件判断问题
R语言switch语句语法.实战:Switch语句用来处理嵌套的if else处理起来比较困难或者麻烦的条件判断问题 目录
- Markdown通用的常用语法说明
前言 Markdown 是一种轻量级的 标记语言,语法简洁明了.学习容易,还具有其他很多优点,目前被越来越多的人用来写作使用. Markdown具有一系列衍生版本,用于扩展Markdown的功能(如表 ...
- jsp 4种常用语法3个编译指令7个动作指令
4种常用语法: 注释:<%--注释--%> 声明:<%!声明部分%> 输出:<%=%> 脚本:可以包含任何java可执行代码.例 <% for(int i=0 ...
- [转]C++/CLI与C#常用语法对比
[转]C++/CLI与C#常用语法对比 Kenny Kerr 一篇名为C++: The Most Powerful Language for .NET Framework Programming文章中 ...
- 每天学一点儿shell:Shell的常用语法规则
文章目录 Shell 参数传递 Shell 数组 Shell 基本运算符 算数运算符 关系运算符 布尔运算符 逻辑运算符 字符串运算符(重点) 文件测试运算符 Shell 常用语法 Shell 函数 ...
- 【shell】常用语法 -b file -c file -f file-d file -x file
[shell]常用语法 -b file -c file -f file-d file -x file 一.test条件判断 1,test文件测试: -b file 若文件存在且 ...
- Go Time常用语法
Go Time常用语法 目录 获取当前时间戳和string类型的格式化时间 构造指定时间 时间戳和格式化时间相互转换 获取当前几月,几号,星期几 待续,用到什么补充什么 1. 获取当前时间戳和stri ...
- Mysql常用语法总结
Mysql常用语法总结如下: #连接mysql数据库(Dos下面) mysql -u root -p 123 #创建数据库 create database myschool; #创建表 drop ta ...
最新文章
- SIM300实现GPRS上网
- JavaSE 6之脚本引擎让程序如虎添翼
- 吐血整理!近二十年全国数学联赛赛题大全,烧脑全集来啦!
- 代码流星雨是什么形式_为什么要在2020年与流星合作
- html5教学文档笔记,4.HTML 教程- (HTML5 基础)
- 看几个源码,自己多做项目了!
- 实现有意识自主学习的智能程序(1)
- 微课|中学生可以这样学Python(6.5节):lambda表达式
- spring boot项目下的application.properties中的logging.level设置日志级别
- Gentoo下搭建DNS中转服务器基本配置
- imreadraw的注册
- android+p+华为手机,Android P六大特性曝光支持刘海屏_华为 P20_手机新闻-中关村在线...
- Unable to instantiate application com.honjane.app.MyApplication
- 肯德尔系数怎么分析_论文实战2——德尔菲法与信度分析
- [POI2012]SZA-Cloakroom
- java识别音高_如何找出音乐的音高
- 修改elementui 的datepicker日期选择器自然周从周一至周日
- 诗歌十一 十二则名门家训(非淡泊无以明志,非宁静无以致远)
- HBase in Practice - 性能、监控及问题解决
- three.js例子
热门文章
- 广告位管理系统---使用说明
- 449A - Jzzhu and Chocolate 贪心
- Illustrator中文版教程,如何在 Illustrator中设置图标项目?
- 如何从 Mac 上的“照片”中导出照片、视频和幻灯片放映?
- ON1 Photo RAW 2022 for Mac(ps/lr滤镜raw图像编辑器)
- 如何保护Mac的数据安全?
- 新上手的Mac怎么开始盘?
- Mac电脑共享“公共文件夹”以外的文件夹的设置教程
- .NET:OrderBy和ThenBy
- 找出数列中个数大于总数一半的元素(编程之美2.3)