Listas em Groovy

Listas em Groovy

1. Visão geral

EmGroovy, podemos trabalhar com listas exatamente como fazemos emJava. Mas, com o suporte a métodos de extensão, é fornecido com um pouco mais.

Neste tutorial, veremos a abordagem do Groovy sobre mutação, filtragem e classificação de listas.

2. Criando listas Groovy

O Groovy fornece certos atalhos interessantes ao trabalhar com coleções, que utiliza seu suporte para digitação dinâmica e sintaxe literal.

Vamos começar criando uma lista com alguns valores usando a sintaxe abreviada:

def list = [1,2,3]

Da mesma forma, podemos criar uma lista vazia:

def emptyList = []

Por padrão, o Groovy cria uma instância dejava.util.ArrayList. No entanto,we can also specify the type of list to create:

def linkedList = [1,2,3] as LinkedList
ArrayList arrList = [1,2,3]

Em seguida, as listas podem ser usadas para criar outras listas usando um argumento construtor:

def copyList = new ArrayList(arrList)

ou por clonagem:

def cloneList = arrList.clone()

Observe que a clonagem cria uma cópia superficial da lista.

O Groovy usa o operador "==" para comparar os elementos em duas listas para igualdade. Continuando com o exemplo anterior, ao compararcloneList comarrlist, o resultado étrue:

assertTrue(cloneList == arrList)

Agora, vamos ver como realizar algumas operações comuns em listas.

3. Recuperando itens de uma lista

Podemos obter um item de uma lista usando a sintaxe literal, como:

def list = ["Hello", "World"]
assertTrue(list[1] == "World")

ou usando os métodosget()egetAt():

assertTrue(list.get(1) == "World")
assertTrue(list.getAt(1) == "World")

Também podemos obter itens de uma lista usando índices positivos e negativos. Quando um índice negativo é usado, a lista é lida da direita para a esquerda:

assertTrue(list[-1] == "World")
assertTrue(list.getAt(-2) == "Hello")

Observe que o métodoget() não suporta índices negativos.

4. Adicionando itens a uma lista

Existem várias maneiras abreviadas de adicionar itens à lista. Vamos definir uma lista vazia e adicionar alguns itens a ela:

def list = []

list << 1
list.add("Apple")
assertTrue(list == [1, "Apple"])

Em seguida, também podemos especificar o índice para colocar o item. Além disso,if the length of the list is less than the index specified, then Groovy adds as many null values as the difference:

list[2] = "Box"
list[4] = true
assertTrue(list == [1, "Apple", "Box", null, true])

Por último, podemos usar o operador “+=” para adicionar novos itens à lista. Em comparação com as outras abordagens,this operator creates a new list object and assigns it to the variable list:

def list2 = [1,2]
list += list2
list += 12
assertTrue(list == [1, 6.0, "Apple", "Box", null, true, 1, 2, 12])

5. Atualizando itens em uma lista

Podemos atualizar itens em uma lista usando a sintaxe literal ou o métodoset():

def list =[1, "Apple", 80, "App"]
list[1] = "Box"
list.set(2,90)
assertTrue(list == [1, "Box", 90,  "App"])

Neste exemplo, os itens no índice 1 e 2 são atualizados com novos valores.

6. Removendo itens de uma lista

Podemos remover um item em um índice específico usando o métodoremove():

def list = [1,2,3,4,5,5,6,6,7]
list.remove(3)
assertTrue(list == [1,2,3,5,5,6,6,7])

Ou também podemos remover um elemento usando o métodoremoveElement(). Isso remove a primeira ocorrência do elemento da lista:

list.removeElement(5)
assertTrue(list == [1,2,3,5,6,6,7])

Além disso,we can use the minus operator to remove all occurrences of an element from the list. Esse operador, no entanto, não modifica a lista subjacente - ele retorna uma nova lista:

assertTrue(list - 6 == [1,2,3,5,7])

7. Iterando em uma lista

Groovy adicionou novos métodos à API JavaCollections existente. Esses métodos simplificam operações como filtrar, pesquisar, classificar, agregar etc, encapsulando o código padrão. Também suportam uma ampla gama de entradas, incluindo fechamentos e estruturas de dados de saída.

Vamos começar examinando os dois métodos para iterar sobre uma lista.

O métodoeach() aceita um encerramento e é muito semelhante ao métodoforeach () em Java. O Groovy passa um parâmetro implícitoit que corresponde ao elemento atual em cada iteração:

def list = [1,"App",3,4]
list.each {println it * 2}

O outro método,eachWithIndex() fornece o valor do índice atual, além do elemento atual:

list.eachWithIndex{ it, i -> println "$i : $it" }

8. Filtragem

A filtragem é outra operação que é frequentemente executada em listas e o Groovy fornece muitos métodos diferentes para você escolher.

Vamos definir uma lista para operar:

def filterList = [2,1,3,4,5,6,76]

Para encontrar o primeiro objeto que corresponde a uma condição, podemos usarfind:

assertTrue(filterList.find {it > 3} == 4)

Para encontrar todos os objetos que correspondem a uma condição, podemos usarfindAll:

assertTrue(filterList.findAll {it > 3} == [4,5,6,76])

Vamos ver outro exemplo. Aqui, queremos uma lista de todos os elementos que são números:

assertTrue(filterList.findAll {it instanceof Number} == [2,1,3,4,5,6,76])

Como alternativa, podemos usar o métodogrep para fazer a mesma coisa:

assertTrue(filterList.grep( Number ) == [2,1,3,4,5,6,76])

The difference between grep and find methods is that grep can accept an Object or a Closure as an argument. Assim, permite reduzir ainda mais a declaração de condição ao mínimo:

assertTrue(filterList.grep {it > 6} == [76])

Além disso,grep usaObject#isCase(java.lang.Object) para avaliar a condição em cada elemento da lista.

Às vezes,we may only be interested in the unique items in a list. Existem dois métodos sobrecarregados que podemos usar para esse fim.

O métodounique() opcionalmente aceita um fechamento e mantém na lista subjacente apenas os elementos que correspondem às condições de fechamento enquanto descarta outros. Ele usa a ordem natural por padrão para determinar a exclusividade:

def uniqueList = [1,3,3,4]
uniqueList.unique()
assertTrue(uniqueList == [1,3,4])

Como alternativa, se o requisito não for alterar a lista subjacente, podemos usar o métodotoUnique():

assertTrue(["A", "B", "Ba", "Bat", "Cat"].toUnique {it.size()} == ["A", "Ba", "Bat"])

Se quisermos verificar se alguns ou todos os itens de uma lista satisfazem uma determinada condição, podemos usar os métodosevery()eany().

O métodoevery() avalia a condição no fechamento em relação a cada elemento da lista. Então, ele só retornatrue se todos os elementos da lista satisfizerem a condição:

def conditionList = [2,1,3,4,5,6,76]
assertFalse(conditionList.every {it < 6})

O métodoany(), por outro lado, retornatrue se algum elemento da lista satisfizer a condição:

assertTrue(conditionList.any {it % 2 == 0})

9. Ordenação

Por padrão, o Groovy classifica os itens em uma lista com base em sua ordem natural:

assertTrue([1,2,1,0].sort() == [0,1,1,2])

Maswe can also pass a Comparator with custom sorting logic:

Comparator mc = {a,b -> a == b? 0: a < b? 1 : -1}
def list = [1,2,1,0]
list.sort(mc)
assertTrue(list == [2,1,1,0])

Além disso, podemos usar os métodosmin() oumax() para encontrar o valor máximo ou mínimo sem chamar explicitamentesort():

def strList = ["na", "ppp", "as"]
assertTrue(strList.max() == "ppp")
Comparator minc = {a,b -> a == b? 0: a < b? -1 : 1}
def numberList = [3, 2, 0, 7]
assertTrue(numberList.min(minc) == 0)

10. Coletando

Às vezes, podemos querer modificar os itens em uma lista e retornar outra lista com valores atualizados. Isso pode ser feito usando o métodocollect():

def list = ["Kay","Henry","Justin","Tom"]
assertTrue(list.collect{"Hi " + it} == ["Hi Kay","Hi Henry","Hi Justin","Hi Tom"])

11. Juntando-se

Às vezes, talvez seja necessário juntar os itens em uma lista. Para fazer isso, podemos usar o métodojoin():

assertTrue(["One","Two","Three"].join(",") == "One,Two,Three")

12. Conclusão

Neste artigo, cobrimos algumas das extensões que o Groovy adiciona à API JavaCollections.

Começamos analisando a sintaxe literal e, em seguida, seu uso na criação, atualização, remoção e recuperação de itens em uma lista.

Finalmente, vimos o suporte do Groovy para iterar, filtrar, pesquisar, coletar, juntar e classificar listas.

Como sempre, todos os exemplos discutidos no artigo estão disponíveisover on GitHub.