「Groovy」- 常用 List 操作

List

Groovy List Tutorial And Examples
A simple way to pretty print nested lists and maps in Groovy.
Groovy – subList() – Tutorialspoint
Combine two lists
How to remove Duplicate Values from a list in groovy – Stack Overflow
Java ArrayList insert element at beginning example
List (Groovy JDK enhancements)
Remove null items from a list in Groovy – Stack Overflow

该笔记将记录:在 Apache Groovy 中,常用 List 操作,以及常见问题处理。

定义列表 | def

def foo = []
def myList = ["Apple", "Banana", "Orange"]
println myList.class // class java.util.ArrayList

基本操作(增删改查)

增:向 List 中添加元素

list.add(element)

// 将元素添加到最开始
list.add(0, element)

// 连接两个列表
["a", "b", "c"] + ["d", "e", "f"]

删:移除 List 中的元素

lst.remove(2) // 删除第 3 个元素

改:修改 List 中的元素:

list.set(2, 11) // 将第 3 个元素修改为 10

获取 | get, getAt, …

Groovy – collect() – Tutorialspoint

list[2]
list.get(2)
list.getAt(2)

// 获取子列表
list.subList(2, 5) // 获取第 3 到 5 间的元素

// 是否包含元素
list.contains(element)

// 获取首个元素或最后的元素
list.first()
list.last()

// collect() | 获取满足条件的元素

lst.collect {element -> return element * element} 

弹出与压入(push & pop)

// pop
def list = ["a", false, 2]
assert list.pop() == 'a'
assert list == [false, 2]

// push
def list = [3, 4, 2]
list.push("x")
assert list == ['x', 3, 4, 2]

打印 | 格式化输出、调试、……

// 直接打印
pritln list

// 美化打印
import static groovy.json.JsonOutput.*
def config = ['test': 'lalala']
println prettyPrint(toJson(config))

检查 | any(), every(), …

Groovy – any() & every() – Tutorialspoint

判断 List 的元素是否满足某些条件:

def lst = [1,2,3,4];
assert lst.any{element -> element > 2} == true
assert lst.every{element -> element > 2} == false

去重 | unique(), toUnique()

String[] letters = ['c', 'a', 't', 's', 'a', 't', 'h', 'a', 't']
assert letters.toUnique() == ['c', 'a', 't', 's', 'h']

但是,这些都不能决定哪个重复的元素被留下:

def list = [
    [ id: 22, name: "Tom"],
    [ id: 12, name: "Mary"],
    [ id: 44, name: "Tom"]
]

def unique = list.toUnique { a, b -> b.name <=> a.name }
assert unique == [[id: 22, name: "Tom"], [id: 12, name: "Mary"]]

// 其实,我们想保留重复元素的最后个,即如下结果:
// [[id: 12, name: Mary], [id: 44, name: Tom]]

// 但是,这种做法只会保留重复元素的第一个

为了保留重复元素的最后一个,我们出此下策:

def list = [
    [ id: 22, name: "Tom"],
    [ id: 12, name: "Marry"],
    [ id: 44, name: "Tom"],
    [ id: 45, name: "Tom"],
    [ id: 46, name: "Marry"],
    [ id: 47, name: "Tom"],
]

def unique = list.reverse().toUnique{a, b -> b.name <=> a.name}.reverse()
assert unique == [[ id: 46, name: "Marry"], [ id: 47, name: "Tom"]]

查找 | find(), findAll()

从 List 中找到符合条件的元素:

def lst = [1,2,3,4];
assert lst.find{element -> element > 2} == 3
assert lst.findAll{element -> element > 2} == [3, 4]

排序 | sort, reverse, …

Sorting Objects By A Specific Property In Groovy | by LoopedNetwork | Medium
java – How to sort a list by existing properties – Stack Overflow
Groovy – reverse() – Tutorialspoint

sort and reverse:

def newList = list.reverse() // 反向排序元素

list.sort{ it.date }
things.sort { a, b ->
    a.name <=> b.name ?: a.title <=> b.title
}

shuffle:

通过 shuffle 方法:
* list.shuffle() // 修改 原 List
* list.shuffled() // 返回 新 List
* 注意,旧版本可能未提供该方法;

通过 Java 方法:
Collections.shuffle(arrayList); 

更新 | collect, …

遍历列表,以生成新列表

def lst = [1, 2, 3, 4]
def newlst = lst.collect {element -> element * element}
println(newlst) // [1, 4, 9, 16]

如果 Closure 没有返回,则会存在 null 元素。使用 findAll 过滤:

newlst.findAll { it != null }

转换 | groupBy, collectEntries

java – shortcut for creating a Map from a List in groovy? – Stack Overflow

def newMap = listFoo.groupBy {it.name} // 将以 it.name 进行聚合,Map 中的每个元素的 value 为 List;

def newMap = listFoo.collectEntries{[(it.name): it]} // 将 it.name 作为 key,将 it 作为 value;

参考文献

Groovy Goodness: Getting the First and Last Element of an Iterable – Messages from mrhaki
groovy – Remove null and empty values using collect with string array – Stack Overflow
is it possible to break out of closure in groovy – Stack Overflow
Iterable (Groovy JDK enhancements)

Set

增 | 创建

groovy – How do you declare and use a Set data structure in groovysh? – Stack Overflow

[“a”, “b”, “c”, “c”].toSet()
[“a”, “b”, “c”, “c”] as Set

注意,Groovy 似乎会忽略 Set 定义,所以 Set<String> s = [“a”, “b”, “c”, “c”] 与 def s = [“a”, “b”, “c”, “c”] 等价。

查 | 查询

setFoo.size()
Groovy has a size property for Collection? – Stack Overflow

改 | 修改

How do I convert a Groovy String collection to a Java String Array? – Stack Overflow
[“a”,”b”,”c”] as String[]

Combine two lists in Groovy – Desktop of ITers
fruits.addAll(newFruits)