由浅入深的了解Groovy的基本使用

0、安装Groovy

1、解压并配置环境变量

GROOVY_HOME=F:\project\Groovy

2、输入groovy -v查看版本信息

在这里插入图片描述

1、了解前提

1.1、什么是Groovy?

Groovy是机遇Java虚拟机的一种敏捷的动态语言,它是一种成熟的OOP(面向对象)编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包动态语言的其他特性。

1.2、于Java相比,Groovy的不同点或优势

1、Groovy完全兼容Java语法,可以做脚本也可以做类

2、分号是可选的,一般不会写,都是使用换行作为结束

3、类、方法、字段都是公开的,没有访问权限限制

4、默认生成具名(名值对)参数构造器 key: value

5、字段不定于访问权限时,编译器自动给字段添加 getter/setter方法

6、字段可以使用点来获取,无访问权限的也可使用getter/setter操作

7、方法可以省略return关键字,自动检索最后一行最为返回值。

8、空值比较不会出现空指针异常。

1.3、Groovy的高级特性

1、assert断言:可以用assert代替之前的Java的断言语句。

2、可选类型:可使用类JavaScript的弱类型,可使用def来表示任意类型。

3、方法调用:调用带参数的方法可以省略括号

4、字符串定义:字符串定义有三种方式,单引号,双引号和三引号

5、集合API:Groovy有自己的API也兼容Java的API

6、闭包:Groovy的一大特性,跟方法类似的代码块,他可以作为一个变量的值,也可以是一个参数传递给一个方法。

{
	// 这样就是一个闭包
}

2、学习路线

2.1、数据语法

2.1.1、list类型

/**
* 添加数据
*/
list = []
// 添加数据
list.push(123)
list << ("123we")
//如果想要强制添加某一个数据需要加上 as 来指定类型
list << (1 as Integer)
list << ("123" as String)

/**
* 遍历数据
*/
for (int i = 0; i < 10; i++) {
    println(list[i])
}
for (iten in list) {
    println("你好")
    println(iten)
}
list.stream().forEach((item) -> {
    println(item)
})
list.each {
    println(it)
}

2.1.2、map

// 定义
def map = [a: 2, b: new Date()]
// 写入
map.put('aaa', 'bbbbb')

// 写入
map.a = 23 as Integer

//println(map)
//println(map.a)

println("----------------------")

2.1.3、在Groovy中任何数据都是对象

// 循环100次
100.times { println(it) }
a = " 123 ".trim()
println(a)
a = true.compareTo(true)
println(a)

2.1.4、类的属性操作更简单

class JavaBean {
    String a;
}
def bean = new JavaBean()
def a = bean.a
println(a)

2.1.5、格式化输出字符串

aa = 10
bb = 1
xx = "我是aa,我的值:${aa};我是bb,我的值:$bb"
println(xx)

2.1.6、switch

def x = new JavaBean()

switch (x) {
    case [1, 2, 3, 4]:
        println("当数据为1,2,3,4中一个数据时就可以走这里")
        break
    case 10..10000:
        println("这里的10..10000表示从10到10000的闭区间所有的整数")
        break
    case Date:
        println("这里表示x是一个时间")
        break
    case JavaBean:
        println("这里表示是一个JavaBean对象")
        break
    default:
        println("都不走走这里")
}

2.1.7、闭包下的默认变量

/**闭包*/


/**
 * it:当闭包方法中,没有定义任何参数时,也可以直接用it遍历
 * */
println("----------it-----------")
list = [1, 2, 3, 4, 5, 6]
list.each { println(it) }

/**
 * this+owner:基本跟this一样,处理一种情况:如果该闭包是在其他的闭包中定义的,那么owner就是只想定义它的闭包对象
 * */
println("----------this+owner-----------")
def xx = {
    println("xx的:" + this)
    println("xx的:" + owner)

    def aa = {
        println("aa的:" + this)
        println("aa的:" + owner)
    }

    aa.call()
}

xx.call()

/**
 * delegate
 * */
println("----------delegate-----------")
def myDelegate = {
    println(this)
    println(owner)
    println(delegate)
}

myDelegate.call()
println("----------执行setDelegate-----------")
myDelegate.setDelegate("abc")
myDelegate.call()

2.1.8、元编程

在Groovy中,可以使用metaClass类来对元数据添加属性和方法

如String类,添加一个uppers方法

aa = "wdwd"
String.metaClass.toUpper = {
    -> toUpperCase();
}
def upper = aa.toUpper()
println(upper)
String.metaClass.to = {
    -> toString()
}
def to = "2".to()
println(to)

2.1.9、强数据类型检查

@TypeChecked
class Type {
    // Integer a = 1.0 这里会报错:Cannot assign 'BigDecimal' to 'Integer'
}


list = [1, 2, 3, 4]
list.push(2 as Integer) // 通过as检查2是不是Integer数据类型

2.1.10、三目运算

/**
 * 三目运算
 * */
a = true
san = a ?: "当a为空或者为false是走这里"

2.1.11、安全访问

/**
 * 安全访问
 * */
class Person {
    String age;
}

Person person = new Person()
def age = person?.age
println(age)

2.2、Groovy自带工具

  • 使用groovyConsole groovy可以启动groovy的自带的idea.

  • groovyc:自带的变异工具,使用他可以拿到编译后的java文件.

  • 使用groovysh可以打开shell可以编写groovy.

  • groovydoc:文件生成工具

在这里插入图片描述

2.3、GDK

2.3.1、自带的集合方法

1、排序
1.1、sort

sort:对集合进行排序,这个方法,可以接受一个闭包参数,或者无参。

/**
 * 排序
 * */

list = [23, 41, 421, 23, 12, 3]

def sortInc = list.sort() // 默认为升序排序
println("排序后:" + sortInc)

// 自定义排序
println("----------自定义排序---------------")
def newList = list.sort({
    a, b -> a - b ? -1 : 1
})
println(newList)

b = -10
c = 1
a = b - c ? -1 : 1 // 只有b和c的值都相等时做减法a的值才为1,其余都为-1
println(a)

1.2、reverse

reverse:将原list倒序,返回一个新的list

2、find
2.1、findAll

findAll:返回符合条件的元素,他可以接收一个闭包参数或者无参。

/**
 * findAll
 * */
def listAll = list.findAll()
println(listAll)

def gl10All = list.findAll({
    a -> a > 100
})
println(gl10All)

def all = list.findAll({
    item ->
        {
            return item == 10;
        }
})

println(all)
2.2、find
list = [1, 1, 1, 1, 1]
def find = list.find({
    item ->
        {
            item == 1
        }
})

find:作用和findAll类似,但是find只会返回第一个符合条件的

2.3、findIndexOf

findIndexOf:返回满足条件的第一个元素的下标值。

3、返回新list
3.1、collect

collect:返回一个新的list,他可以接受一个闭包参数或者无参。

println("--------------collect---------------")
def collect = list.collect()
println(collect)

def doCollect = list.collect({
    println("每一个it为:" + it)
    if (it == 10) {
        return it * it
    }
    return it - 1;
})


println(doCollect)
3.2、tail

tail:返回一个新的list,它包含list中的所有的元素(除了第一个元素)

4、inject

inject:一个累积的过程方法(有点像js的reduce),传入inject方法中的ini作为sum的初始值,在遍历collection的过程中,讲处理结果(“$sum $elem”)保存到sum中。

list = ["love", "hello"]

/**
 * "$elem $sum"可以理解为字符串的拼接,$sum作为起始值还是作为做后的值只需看他在$elem的前面还是后面
 *      如果$sum在后面说明每一次拼接新的元素都在最前面
 *      如果$sum在前面说明每一次拼接新的元素都在最后面
 * */

def aa = list.inject("ini") {
    sum, elem -> "$elem $sum"
}


println(aa)
5、eacheachWithIndex
  • each:普通的迭代遍历
  • eachWithIndex:他的作用和each一样,但是他要传入一个闭包,有两个参数,一个是值,一个是索引。
list = [1233213, 312, 31, 23, 12, 31, 23, 12, 3, 123, 1, 24, 12, 4, 2435, 34, 5]
list.each({
    it -> println(it)
})

list.eachWithIndex { int entry, int i ->
    {
        println(entry + "--------------" + i)
    }
}
6、every

every:接收一个闭包,返回为一个布尔值,当所有条件都满足时才返回true

def every = list.every(item -> {
    item > 0
})

println(every)
7、any

any:和every的使用相同,只不过any的条件中只要有一个为真那么就返回真。

8、first

first:返回list的第一个元素

def first = list.first()
println(first)
9、last

last:返回list的最后一个元素

println(list.last())
println(list.lastIndexOf(10))
// 在原数组删除最后一个元素,返回为被删除的数据
def last = list.removeLast()
println(list)
println(last)
// 删除数组中最大的元素
def last1 = list.sort().removeLast()
println(last1)
10、groupBy、unique、max、min、count、sum等
def max = list.max()
println(max)

println(list.min())
println(list.unique())
println(list.sum())

2.3.2、通配符

*:可以很方便的访问集合对象所有的属性

@TypeChecked
class Car {
    String make
    String model
}

def cars = [
        new Car(make: UUID.randomUUID().toString(), model: UUID.randomUUID().toString()),
        new Car(make: UUID.randomUUID().toString(), model: UUID.randomUUID().toString())
]


def car_model = cars*.model
car_model.each {
    println(it)
}

def numbers = 2..10.multiply(2) // Number:https://blog.csdn.net/u011422561/article/details/91353477
println(numbers)

def upperCase = ["driver", "sky"]*.toUpperCase()
println(upperCase)

2.3.3、GPath

像Xpath语法一样可以轻松访问多层的集合对象。

a = [
        ["a": 123],
        ["a": 1],
        ["a": 12]
]

println(a.a.max())

2.3.4、IO操作

1、普通文件操作
// 创建文件并读取内容
def file = new File('./1.txt').text
println(file)

// 如果没有当前文件就创建文件
def file1 = new File("./file.txt")
// 将内容写入文件
//file1.text = "123213dawd"

String fileName = './file.txt'
// 通过字节的形式操作文件
def file2 = new File(fileName).bytes
println(file2)

// 读取文件内容,然后一行一行的输出
new File(fileName).eachLine { line ->
    println(line)
}
2、InputStream操作
// 通过流的形式读取
def propertiesFile = new File('./test.properties')  // 内容为:name=re
Properties properties = new Properties();
propertiesFile.withInputStream {
    properties1.load(it)
}

def name = properties.name
println(name)
3、Reader操作
// 通过Reader进行文件的读取操作
def lineNo = 1
def line = 1;
new File(fileName).withReader {
    reader ->
        {
            while ((line = reader.readLine() != null)) {
                println("第${lineNo}行内容:${line} ----- ${reader.readLine()}")
                lineNo++;
            }
        }
}
4、Writer操作

基本操作

new File('./dwd.txt').withWriter('utf-8', {
    writer -> writer.writeLine('hello world')
})

精简版本

// Writer的精简版本
new File('精简版本.txt') << '''
    这是一个精简版本的文件
    new File('精简版本')
'''
5、操作Url
// Url操作
def text = "http://ww.baidu.com".toURL().text
println(text)
6、Ranges 用 … 表示范围

返回

// 操作返回
println((1..10)*.multiply(2))
println((10..1)*.multiply(2))

('a'..'z').each { println(it) }

截取

text = "hello world"
println(text[0..2])

(1..<6).each { println(it) }

2.3.5、工具

1、ConfigSlurper

ConfigSlurper工具可以对读取配置文件十分方便

def config = new ConfigSlurper().parse(
        '''
            app.data=new Date()
        '''
)


def pp = config.toProperties()

println(pp."app.data")
2、Expando

Expando类是Groovy语言的一个相当有趣的类

他的作用类似于GroovyBean类,但是比他更灵活,同时他还类似于Map类,但也比Map更加灵活。

def expando = new Expando();
expando.name = { -> "abc" }
expando.say = {
    String s -> "${expando.name} say ${s}"
}

def say = expando.say("hello")
println(say)

def person = new Expando();

person.name = "zhangsan"
person.age = 18

person.des = {
    println("""
        -----------description-----------
    """)
}
person.des()
3、添加监听
def list = new ObservableList()
def printer = {
    e -> println(e.class)
}
list.addPropertyChangeListener(printer)
list.add('hello world1')
list.add('hello world2')
list.add('hello world3')
list.remove(0)

2.4、Java新特性

2.4.1、参数默认值

可以对定义的方法参数设置默认值

def func(args = "abc"){
    println(args);
}

2.4.2、注解

  • 使用@ToString可以帮助用户提供运行时的数据信息。

  • 使用@EqualsAndHashCode注解可以使equals相等的两个对象的hashCode也相等

  • 使用@TupleConstructor注解可以在传javaBean的数据时,免去传key,直接传value

  • @Canonical注解时以上三个注解的合体。

2.4.3、正则表达式

只需要用 ~/表达式/, 匹配时用:需要匹配的字符=~/正则/;

def email = "2463983565@qq.com"
def isEmail = email ==~ /[\w.]/

println(isEmail)

2.4.4、被弱化的泛型

@CompileStatic
class LsitS {
    List<String> list = ["123"];
}

2.4.5、Groovy的数字类型

在默认情况下groovy的数字类型都是BigDecimal类型,但是想要数字类型编程double,float,long类型的数字,只需要在数字后面加上c,f,l。

2.4.6、Boolean的自动转换

默认情况下groovy会把空字符串、0,null的if条件语句转成false,其他的转成true,这个特性和js、python一样

2.4.7、map语法糖

groovy允许我们把一个变量当做map的key或者value

def key = 1;
def value = 2;
def map = [(key): value]
println(map)

2.5、内置用法

2.5.1、自定义不存在方法的调用逻辑

class AAA {
    def methodMissing(String name, args) {
        println("没有这个方法")
    }
}

def aaa = new AAA()
aaa.dw();

2.5.2、使用@Delegate注解,可以实现方法的拷贝

class B{
	@Delegate final Person person; // 将person中的所有方法拷贝过来
}

2.6、DSLs

2.6.1、基本使用

  • 可以通过delegate属性可以直接实现
package dsl

public class SMS {
    def form(String a) {
        println("from ${a}")
    }

    def to(String a) {
        println("to ${a}")
    }

    def body(String body) {
        println("body:${body}")
    }

    def bodyDSL(String dsl) {
        println("dsl:${dsl}")
    }

    def send() {
        println("send..........")
    }

    def static send(block) {
        def msm = new SMS();
        block.delegate = msm;
        block();
        msm.send()
    }
}

SMS.send({
    form: "fromD"
    to: "toD"
    body: "I am body"
})

  • 另一个dsl例子
show = { println(it) }

sq_root = { Math.sqrt(it) }

def please(action) {
    [
            then: {
                what ->
                    [
                            of: { n -> action(what(n)) }
                    ]
            }
    ]

}

please(show).then(sq_root).of(100)

2.6.2、覆盖操作符

OperatorMethod
a + ba.plus(b)
a - ba.minus(b)
a * ba.multiply(b)
a ** ba.power(b)
a / ba.div(b)
a % ba.mod(b)
a | ba.or(b)
a & ba.and(b)
a ^ ba.xor(b)
a++a.next()
a–a.previous()
a[b]a.getAt(b)
a[index] = ca.putAt(index, c)
a << ba.leftShift(b)
a >> ba.rightShift(b)
a >>> ba.rightShiftUnsigned(b)
a >>> ba.leftShiftUnsigned(b)
switch(a){case (b): }b.isCase(a)
if(a)a.asBoolean()
~aa.bitwiseNegate()
-aa.negative()
+aa.positive()
a as ba.asType(b)
a == ba.equals(b)
a != b!a.equals(b)
a <=> ba.compareTo(b)
a > ba.compareTo(b) > 0
a < ba.compareTo(b) < 0
a >= ba.compareTo(b) >= 0
a <= ba.compareTo(b) <= 0

2.6.3、操作属性get|set

class MyList {
    def list = [1, 2, 3, 4]

    def setAt(Integer a) {
        this.list.add(a)
    }
}

MyList l = new MyList();
def list = l.getList()
println(list)

2.6.4、魔法方法

class MyList {

    def propertyMissing(String name) {
        println("属性:${name}不存在")
    }

    def methodMissing(String name) {
        println("方法:${name}不存在")
    }

}

2.7、trait关键字

traits关键字相当于jdk8的接口类,可以实现默认方法。也可抽象方法。

  • 如果定义抽象方法时,要加上abstract关键字
  • 可以实现具体的方法

2.8、函数式编程

2.8.1、基本使用

list = [1, 2, 4, 6, 8]

// 函数和闭包
static def finds(list, tester) {
    for (item in list) {
        if (tester(item)) {
            return item
        }
    }
}

def i = finds(list, {
    it > 2
})

println(i)

2.8.2、@Immutable注解 (类似final)

放在类上,可以对所有的属性进行final的操作相同。

2.8.3、利用groovy的迭代方法进行流畅操作

// 批量截取字符串
list = ["dwawa", "dwawa", "dwawa", "dwawa"]
def collect = list.collect(it -> {
    it.substring(1)
})
println(list)
println(collect)

// 判断若干个对象的name的谁的最长
def student1 = new Student("31233123123123")
def student2 = new Student("3123123123")
def student3 = new Student("3123213123dsa3123")

list = []
list.add(student1)
list.add(student2)
list.add(student3)

def studentName =
        list
                .findAll((item) -> { item.name != null })
                .collect((item) -> { item.name })
                .inject("") { n1, n2 ->
                    {
                        n1.length() >= (((n2 as String).length()) as Integer) ? n1 : n2
                    }
                }
println(studentName)

2.8.4、curry(咖喱)方法

可以预设一些参数

con = { x, y -> return x + y }
br = con.curry("dwa")

println(br("x"))
    

// 返回值为dwax

2.8.5、业务处理逻辑

class A {
    static print(name) { println("${name}") }
}


[1, 2, 3, 4, 4, 5].each { A.print(it) }

2.8.6、防止递归溢出

@TailRecursive
// 这个注解会将方法放入堆里面,而不是压栈
  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值