加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Groovy探索之Gpath和List的结合 更加Groovy风格的代码

发布时间:2020-12-14 16:55:52 所属栏目:大数据 来源:网络整理
导读:??????????????? Groovy探索之Gpath和List的结合 更加Groovy风格的代码 ? ? 在使用Groovy语言的日子里,我常常都被一些Groovy的风格所惊喜着。如闭包、each等方法、Gpath、Map参数等等,等等。我不知道其他动态语言是否也具有这样的一些风格,但起码这些风格

??????????????? Groovy探索之Gpath和List的结合 更加Groovy风格的代码

?

?

在使用Groovy语言的日子里,我常常都被一些Groovy的风格所惊喜着。如闭包、each等方法、Gpath、Map参数等等,等等。我不知道其他动态语言是否也具有这样的一些风格,但起码这些风格是区别于Java语言的风格。我是多年的Java程序员,遇到这些简单、易懂的风格,难免会惊喜不已。

很多的Groovy语言风格我们很容易接受,如each方法,Gpath语句。

比如,我们有了如下的一个List对象:

?

??? ? def list = [1,2,3,4]

?

我们在Groovy语言里要遍历这个list对象,我们肯定会轻松的使用下面的each方法:

?

??? ? list.each{

?????? ? println it

??? ? }

?

而不会使用下面的for循环:

?

??? ? for(int it in list)

??? ? {

?????? ? println it

??? ? }

???

?

这些都是非常简单和明了的,就像我们会使用了Gpath语句,谁还会使用对于Bean对象的属性操作的"set"和"get"方法呢?

但是有一些Groovy语言风格的代码,却不是那么容易写得出来,特别是对于我们这些Java程序员来说。

但是,我们一旦学会的那些Groovy语言风格的代码,却会给我们带来更大、更多的惊喜。而这些本文所要说到的。

正如标题所言,我们今天要说到的Groovy语言风格的代码,是结合了List对象的一些方法和Gpath语句的代码。

?

比如,我们有如下的一个Map对象,用来表示一些城市和她们所在的国家:

?

?

??? ? def cities = ['Shanghai':'China','New York':'USA','Pairs':'France','Beijing':'China']

?

现在,我们想知道在这个Map对象中,所在国为中国的城市有哪些?在Java语言中,我们会毫不犹豫的写出如下的代码:

?

??? ? def citiesInChina = []

??? ? cities.each{

?????? ? if(it.value=='China')

?????? ? {

?????????? ? citiesInChina << it.key

?????? ? }

??? ? }

??? ?

??? ? println citiesInChina

???

而在Groovy语言中,我们的具有Groovy语言风格的代码应该是如下的形式:

??? ?

??? ? def citiesInChina = cities.findAll{

?????? ? it.value == 'China'

??? ? }.collect{it.key}

??? ?

??? ?

??? ?

??? ? println citiesInChina

???

从上面的代码,我们可以初步的看到集合方法和Gpath结合起来的代码风格的威力。但这还不是最经典的例子。

比如我们有如下的一些GroovyBean:

?

class Book {

???

??? String name

???

??? List authors

?

?

}

?

class Author {

???

??? String name

???

??? Address addr

?

?

?

}

?

class Address {

???

??? String province

???

??? String city

?

}

上面的GroovBean的层次结构有点复杂,简单说来就是:一本书有一个或多个作者,每一个作者又都有属于自己的地址。现在,我们有如下的一个初始化数据:

??????

?????? def addr1 = new Address(province:'Guangdong',city:'Shenzhen')

?????? def addr2 = new Address(province:'Gunagdong',city:'Guangzhou')

?????? def addr3 = new Address(province:'Hunan',city:'Changsha')

?????? def addr4 = new Address(province:'Hubei',city:'Wuhan')

??????

?????? def books = [new Book(name:'A glance at Java',authors:[new Author(name:'Tom',addr:addr1)]),

?????? ???????????? new Book(name:'Deep into Groovy',addr:addr1),new Author(name:'Mike',addr:addr3)]),

?????? ???????????? new Book(name:'A compare of Struts and Grails',authors:[new Author(name:'Wallace',addr:addr4),new Author(name:'Bill',addr:addr2)]),

?????? ???????????? new Book(name:'learning from Groovy to Grails',addr:addr3)])]

???

在上面的数据中,books变量是由多本书组成,而那些书,有的有一个作者,有的有多个作者,但每个作者都有他自己的地址。

现在,我们想找出作者是"Tom"的书籍的书名。在Java语言中,我们就会有如下形式的代码:

?????? def booksOfTom = []

??????

?????? books.each{

?????????? def book = it

?????????? def aus = it.authors

??????????

?????????? aus.each{au->

????????????? if(au.name=='Tom') booksOfTom<<book.name

?????????? }

?????? }

??????

??????

??? println booksOfTom

?

但是,上面的需求,在Groovy语言中是如下风格的代码:

?????? def booksOfTom = books.grep{

?????????? it.authors.any{it.name=='Tom'}

?????? }.name

??? println booksOfTom

?

首先,对"books"使用"grep"方法,最后得到的结果应该是一个"Book"对象的集合,再对该集合取"name",在这里,".name"相当于"*.name"。

在"grep"方法内部,"it.authors"取得了所有的作者,然后再通过"any"方法来遍历作者名为"Tom"的"Book"对象。

这就是结合集合方法和Gpath的Groovy代码风格,开始学起来有一定的难度,但是理解之后,这种代码风格、这种方法十分好用。下面再举一例。

比如,我们想取得作者是"Wallace"的作者所在的城市(这里有重名的作者)。Java语言的编码风格应该是这样的:

?????? def citiesOfWallace = []

?

?????? books.each{

?????????? def book = it

?????????? def authors = it.authors

?????????? authors.each{

????????????? author->

????????????????? if(author.name == 'Wallace')

????????????????? {

???????????????????? def addr = author.addr

???????????????????? citiesOfWallace << addr.city

????????????????? }

?????????? }

?????? }

?

??? println citiesOfWallace

?

但是Groovy语言却会写出如下风格的代码来:

?

?????? def citiesOfWallace = books.authors.flatten().grep{

?????????? it.name == 'Wallace'

?????? }.addr.city

??????

??????

??? println citiesOfWallace

?

"books.authors"的结果是一个集合对象,它里面是由四个集合对象组成,这四个集合对象中的每一个集合对象都是由"Author"对象组成。因此对它们进行"flatten"方法,直接获得一个集合对象,由"Author"对象组成。

然后再进行"Author"对象的"name"属性是否为"Wallace"的匹配,匹配完成,得到一个由"Author"对象组成的集合对象。

最后进行取".addr.city",得到一个由"city"组成的集合。也就是需要的结果。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读