groovy脚本语言基础1

时间:2023-03-09 18:54:22
groovy脚本语言基础1

一 搭建groovy环境

安装JDK

[root@node1 ~]# yum  -y install java-11-openjdk

官网下载groovySDK下载

https://groovy.apache.org/download.html,使用最新的稳定版本3.0

[root@node1 ~]# cd /usr/local/src/

[root@node1 src]# ll

-rw-r--r-- 1 root root 73717075 May  8 09:13 apache-groovy-sdk-3.0.3.zip

[root@node1 src]# unzip apache-groovy-sdk-3.0.3.zip

[root@node1 src]# cd groovy-3.0.3/

rwxr-xr-x  2 root root  4096 Apr  7 16:22 bin
drwxr-xr-x 2 root root 33 Apr 7 16:22 conf
drwxr-xr-x 4 root root 63 Apr 7 16:22 doc
drwxr-xr-x 2 root root 73 Apr 7 16:22 grooid
drwxr-xr-x 2 root root 4096 Apr 7 16:22 indy
drwxr-xr-x 3 root root 4096 Apr 7 16:22 lib
-rw-r--r-- 1 root root 14895 Apr 7 16:15 LICENSE
drwxr-xr-x 2 root root 267 Apr 7 16:22 licenses
-rw-r--r-- 1 root root 1574 Apr 7 16:15 NOTICE
drwxr-xr-x 12 root root 309 Apr 7 16:22 src

配置环境变量

[root@node1 bin]# vim  /root/.bash_profile

export PATH="$PATH:/usr/local/src/groovy-3.0.3/bin/"
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.7.10-4.el7_8.x86_64/
PATH=$PATH:$HOME/bin:$JAVA_HOME/bin

[root@node1 bin]# java -version

openjdk version "11.0.7" 2020-04-14 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.7+10-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.7+10-LTS, mixed mode, sharing)

[root@node1 bin]# groovy -v

Groovy Version: 3.0.3 JVM: 11.0.7 Vendor: Oracle Corporation OS: Linux

二 Ubuntu18.04 安装 Idea 2018.2 Ultimate

2.1 环境信息

OS:Ubuntu18.04
JDK:1.8
Idea: 2018.2 Ultimate

2.2 下载Idea 2018.2安装

到jetbrains官网,选择Ultimate版本的tar.gz包下载

groovy脚本语言基础1

root@darren-virtual-machine:/IDEA# pwd

root@darren-virtual-machine:/IDEA# cp /root/Downloads/ideaIU-2020.1.1.tar.gz  ./

root@darren-virtual-machine:/IDEA# tar -xf ideaIU-2020.1.1.tar.gz

root@darren-virtual-machine:/IDEA# chmod 755 -R idea-IU-201.7223.91/

root@darren-virtual-machine:/IDEA# cd idea-IU-201.7223.91/

root@darren-virtual-machine:/IDEA/idea-IU-201.7223.91# cd bin/

root@darren-virtual-machine:/IDEA/idea-IU-201.7223.91/bin# ./idea.sh

groovy脚本语言基础1

使用免费的三十天的

groovy脚本语言基础1

2.3 安装groovy环境

使用相同的方法安装Java和groovy

root@darren-virtual-machine:/IDEA# apt-get install openjdk-8-jdk

root@darren-virtual-machine:/IDEA# cp /root/Downloads/apache-groovy-sdk-3.0.3.zip   /IDEA/

root@darren-virtual-machine:/IDEA# unzip apache-groovy-sdk-3.0.3.zip

配置环境变量

root@darren-virtual-machine:/IDEA/groovy-3.0.3/bin# vi /root/.bashrc

JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64/
GROOVY_HOME=/IDEA/groovy-3.0.3/
PATH=$PATH:$JAVA_HOME/bin:$GROOVY_HOME/bin
export JAVA_HOME PATH GROOVY_PATH

root@darren-virtual-machine:/IDEA/groovy-3.0.3/bin# source /root/.bashrc
root@darren-virtual-machine:/IDEA/groovy-3.0.3/bin# groovy -v

Groovy Version: 3.0.3 JVM: 1.8.0_252 Vendor: Private Build OS: Linux

2.4 使用idea创建一个groovy项目

groovy脚本语言基础1

groovy脚本语言基础1

创建一个class类型的groovy的文件

groovy脚本语言基础1

groovy脚本语言基础1

根据Java语法,写一个简单代码

public class hellogroovy {
public static void main(String[] args){
System.out.println("Heelo Groovy");
}
}

执行

groovy脚本语言基础1

不用创建类和对象,直接使用groovy输出

println "hello groovy"

这里虽然使用的是脚本语言编写的,但是实际自己生成编译一个文件,最终还是应用程序类型

groovy脚本语言基础1

groovy的的基础语法

三 groovy变量

3.1 变量的基本类型

groovy变量的类型,基本都是对象类型

groovy脚本语言基础1

创建一个variable的包

groovy脚本语言基础1

在这个包下创建一个groovy script

groovy脚本语言基础1

groovy脚本语言基础1

写一个变量,查看变量的类型

groovy脚本语言基础1

结果如下,整形在经过groovy处理后,也会变成对象类型

groovy脚本语言基础1

同理

groovy脚本语言基础1

3.2 变量的定义

使用def定义变量

groovy脚本语言基础1

groovy会主动识别变量的类型,弱类型定义,使用强类型转换,则变量不会动态的转换,保证数据的正确性

当使用def定义的变量后,在后面可以任意定期其他类型的变量代替

groovy脚本语言基础1

groovy的字符串string定义

常用的定义方式

groovy脚本语言基础1

使用三引号定义有格式的字符串

groovy脚本语言基础1

双引号丁克可扩展字符串

groovy脚本语言基础1

可扩展的不仅仅是$变量,也可以是其他表达式

groovy脚本语言基础1

string个Gstring的相互转换

groovy脚本语言基础1

3.3 String方法

普通类型常用参数的方法

1.字符串填充

groovy脚本语言基础1

字符串比较

groovy脚本语言基础1

获取字符串的内容及其他方法

def str = "groovy HelloWorld"
def str2 = "Hello"
println str[0] //取出第一个字母
println str[0..2] //取出前三个字母
println str.minus(str2) //减法
println str - str2 //groovy减法
println str.reverse() // 倒序
println str.capitalize() //首字母大写
println str.isNumber() //判断是否为数字

结果

groovy脚本语言基础1

四 groovy逻辑控制

4.1 case语句

package variable
def x=1.23
def result
switch (x){
case 'foo':
result = 'found foo'
break
case 'bar':
result = 'found bar'
break
case [4,5,6,'inlist']: //列表
result = 'list'
break
case 12..30: //范围
result = 'range'
break
case Integer:
result = 'Integer'
break
case BigDecimal:
result = 'big decimal'
break
default: result = 'default'
}
println result

执行结果

groovy脚本语言基础1

4.2 for循环

对范围的循环

def sum = 0
for(i in 0..9){
sum += i
}
println sum

对list的循环

sum = 0
list = [1,2,3,4,5]
for (i in list){
sum += i
}
println sum

对map进行循环

sum = 0
map_vaule = ['num1':1,'num':2,'num3':3]
for (i in map_vaule){
sum += i.value
}
println sum 

五 groovy闭包

5.1 基本使用

package variable
def clouser = {println 'Hello Groovy'}
clouser.call() //call调用
clouser() //直接调用,类似于一个方法 

5.2 闭包调用参数

package variable

import org.stringtemplate.v4.ST

def clouser = { String name -> println "Hello ${name}"}
clouser.call('world')
clouser('groovy')
def name = "Groovy"
clouser(name) println "*****************************************************************"
//多个参数
def clouser_1 = { String name_1,age -> println "Hello ${name_1},My age is ${age}"}
def name_1 = "John"
clouser_1(name_1,4) println "*****************************************************************"
// 默认参数it
def clouser_2 = { println "Hello ${it}"}
def name_3 = "joy"
clouser_2(name)
println "*****************************************************************"
//闭包返回值
def clouser_3 = {String name_4 ->
return "Hello $name_4"
}
def name_4 = "jolly"
result = clouser_3(name_4)
println result
println "*****************************************************************"
//没有return,也会有返回值,返回值为null
def clouser_4 = {String name_5 ->
println "Hello $name_5"
}
def name_5 = "wellian"
result = clouser_4(name_5)
println result 

结果如下

groovy脚本语言基础1

5.3 闭包与基本类型使用

package variable
import org.stringtemplate.v4.ST
println "闭包函数使用"
println "*****************通过upto实现阶乘**************************"
int x = fab(5)
println x
int fab(int number){ //定义一个闭包函数
int result = 1 //初始值为1
//1调用upto方法,从1到number,做一个1到10的阶乘
1.upto(number,{ num -> result *= num})
return result
} //通过downto实现阶乘
println "*****************通过downto实现阶乘**************************" int fab2(int number){
int result = 1
//number.downto(1,{num -> result *= num})
number.downto(1){num -> result *= num}
return result
}
int y = fab2(5)
println y //times实现阶乘
println "*****************通过times实现求和**************************"
int z = cal(101)
println z
int cal(int number){
int result=0
number.times {
num -> result += num //阶乘不能使用times方法,因为看源码,times都是从0开始,不能使用阶乘
}
return result
}

执行结果

闭包函数使用
*****************通过upto实现阶乘**************************
120
*****************通过downto实现阶乘**************************
120
*****************通过times实现求和**************************
5050

5.4 闭包和String结合的使用

package variable
import org.stringtemplate.v4.ST
println "闭包函数和字符串结合使用"
String str = 'the 2 and 3 is 5'
println "each遍历"
str.each {
String temp -> print temp //使用println每次换行输出
}
println "\n"
println "***********each的返回值是str本身*****************"
println str.each{ }
println "***********fin方法查找符合条件的第一个****************"
println str.find{
String s -> s.isNumber() //第一个数字
}
println "***********findAll方法查找符合条件的第一个****************"
def list = str.findAll{
String s -> s.isNumber() //所有数字,findall结果是一个集合,可以转换成列表
}
println list.toListString() println "***********any方法查找符合条件,返回的是一个bool值****************"
def result = str.any {
String s-> s.isNumber()
}
println result
println "***********every方法所有都符合条件,返回的是一个true****************"
println str.every {
String s -> s.isNumber()
}
println "***********使用collect方法,遍历所有内容****************"
def list2 = str.collect{
it.toUpperCase() //使用默认参数,同时吧所有的字母转换为大写
}
println list2.toListString()

结果

闭包函数和字符串结合使用
each遍历
the 2 and 3 is 5 ***********each的返回值是str本身*****************
the 2 and 3 is 5
***********fin方法查找符合条件的第一个****************
2
***********findAll方法查找符合条件的第一个****************
[2, 3, 5]
***********any方法查找符合条件,返回的是一个bool值****************
true
***********every方法所有都符合条件,返回的是一个true****************
false
***********使用collect方法,遍历所有内容****************
[T, H, E, , 2, , A, N, D, , 3, , I, S, , 5]

5.5 groovy闭包的三个变量,this.owner.delegate

package variable
import org.stringtemplate.v4.ST
println "闭包函数的三个重要变量,this,owner,delegate"
def scriptClouser = {
println "scriptClouser this:"+this //代表闭包定义的类
println "scriptClouser owner:"+owner //代表闭包定义处的类或者对象
println "scriptClouser delegate:"+delegate //代表任意对象,默认和owner一致
}
scriptClouser.call() //使用call可以明显知道是调用的闭包 //定义一个内部类
class Person{
def static classClouser = {
println "classClouser this:"+this
println "classClouser owner:"+owner
println "classClouser delegate:"+delegate
}
def static say(){
def classClouser = {
println "methodClassClouser this:"+this
println "methodClassClouser owner:"+owner
println "methodClassClouser delegate:"+delegate
}
classClouser.call()
}
}
Person.classClouser.call()
Person.say()

执行

package variable
import org.stringtemplate.v4.ST
println "闭包函数的三个重要变量,this,owner,delegate"
def scriptClouser = {
println "scriptClouser this:"+this //代表闭包定义的类
println "scriptClouser owner:"+owner //代表闭包定义处的类或者对象
println "scriptClouser delegate:"+delegate //代表任意对象,默认和owner一致
}
scriptClouser.call() //使用call可以明显知道是调用的闭包 //定义一个内部类
class Person{
def static classClouser = {
println "classClouser this:"+this
println "classClouser owner:"+owner
println "classClouser delegate:"+delegate
}
def static say(){
def classClouser = {
println "methodClassClouser this:"+this
println "methodClassClouser owner:"+owner
println "methodClassClouser delegate:"+delegate
}
classClouser.call()
}
}
Person.classClouser.call()
Person.say()

闭包定义一个闭包

package variable
import org.stringtemplate.v4.ST
println "闭包函数的三个重要变量,this,owner,delegate"
//定义一个内部类
class Person{
def classClouser = {
println "classClouser this:"+this
println "classClouser owner:"+owner
println "classClouser delegate:"+delegate
}
def say(){
def classClouser = {
println "methodClassClouser this:"+this
println "methodClassClouser owner:"+owner
println "methodClassClouser delegate:"+delegate
}
classClouser.call()
}
} Person p = new Person()
p.classClouser.call()
p.say()
//定义闭包内一个闭包
//当在内部类中定义一个闭包,则这三个值一样的,但是适应闭包的闭包,就不会一致了
def nestClouser = {
def innerClouser = {
println "innerClouser this:"+this
println "innerClouser owner:"+owner
println "innerClouser delegate:"+delegate
}
innerClouser.call()
}
nestClouser.call()

结果

闭包函数的三个重要变量,this,owner,delegate
classClouser this:variable.Person@6e46d9f4
classClouser owner:variable.Person@6e46d9f4
classClouser delegate:variable.Person@6e46d9f4
methodClassClouser this:variable.Person@6e46d9f4
methodClassClouser owner:variable.Person@6e46d9f4
methodClassClouser delegate:variable.Person@6e46d9f4
innerClouser this:variable.closestudy@644c78d4
innerClouser owner:variable.closestudy$_run_closure1@532a02d9
innerClouser delegate:variable.closestudy$_run_closure1@532a02d9

修改默认的delegate

package variable
import org.stringtemplate.v4.ST
println "闭包函数的三个重要变量,this,owner,delegate"
//定义一个内部类
class Person{
def classClouser = {
println "classClouser this:"+this
println "classClouser owner:"+owner
println "classClouser delegate:"+delegate
}
def say(){
def classClouser = {
println "methodClassClouser this:"+this
println "methodClassClouser owner:"+owner
println "methodClassClouser delegate:"+delegate
}
classClouser.call()
}
} Person p = new Person()
//p.classClouser.call()
//p.say()
//定义闭包内一个闭包
//当在内部类中定义一个闭包,则这三个值一样的,但是适应闭包的闭包,就不会一致了
def nestClouser = {
def innerClouser = {
println "innerClouser this:"+this
println "innerClouser owner:"+owner
println "innerClouser delegate:"+delegate
}
innerClouser.delegate = p //修改默认的delegate对象
innerClouser.call()
}
nestClouser.call()

执行结果

闭包函数的三个重要变量,this,owner,delegate
innerClouser this:variable.closestudy@4a8ab068
innerClouser owner:variable.closestudy$_run_closure1@611f8234
innerClouser delegate:variable.Person@7bb3a9fe
  1. 大多数情况下,this  owner  delegate的值是一样的
  2. 当使用闭包的闭包,owner delegate就和this不一样了
  3. 当人为修改delegate对象,这三个就完全不一样(this和owner不能修改)

5.6 闭包函数的委托策略

package variable
import org.stringtemplate.v4.ST
println "闭包函数的委托策略"
class Student{
String name
def pretty= { "My name is ${name}" }
String toSting(){
pretty.call()
}
}
class Teacher{
String name
} def stu = new Student(name:'natasha')
def tea = new Teacher(name: 'John')
println stu.toSting() //结果是My name is natasha
//修改delegate的默认对象
stu.pretty.delegate = tea
//使用委托策略,当Deletgate没有值,就会继续从student中寻找,比如修改String name1 和def tea = new Teacher(name1: 'John'),输出的值依然是natasha,这时如果委托策略修改为Clouser.DELEGATE_ONLY,代码就会报错
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.toSting()

执行

闭包函数的委托策略
My name is natasha
My name is John

参考:https://www.bilibili.com/video/BV1nt411b7dE?p=13