Elementen zoeken in collecties in Groovy

1. Inleiding

Groovy biedt een aanzienlijk aantal methoden die de kerncapaciteiten van Java verbeteren.

In deze tutorial laten we zien hoe Groovy dit doet wanneer zoeken naar een element en het vinden in verschillende soorten collecties.

2. Test of het element aanwezig is

Ten eerste zullen we ons concentreren op het testen of een bepaalde verzameling een element bevat.

2.1. Lijst

Java biedt zelf verschillende manieren om zoeken naar een item in een lijst met java.util.List:

  • De bevat methode
  • De index van methode

Omdat Groovy een Java-compatibele taal is, kunnen we ze veilig gebruiken.

Laten we een voorbeeld bekijken:

@Test void whenListContainsElement_thenCheckReturnsTrue () {def list = ['a', 'b', 'c'] assertTrue (list.indexOf ('a')> -1) assertTrue (list.contains ('a'))}

Afgezien daarvan, Groovy introduceert de lidmaatschapsoperator:

element in lijst

Het is een van de vele syntactische suikeroperatoren van Groovy. Met zijn hulp kunnen we onze code vereenvoudigen:

@Test ongeldig whenListContainsElement_thenCheckWithMembershipOperatorReturnsTrue () {def list = ['a', 'b', 'c'] assertTrue ('a' in lijst)}

2.2. Set

Net als bij het vorige voorbeeld kunnen we de java.util.Set # bevat methode en de in operator:

@Test void whenSetContainsElement_thenCheckReturnsTrue () {def set = ['a', 'b', 'c'] als Set assertTrue (set.contains ('a')) assertTrue ('a' in set)}

2.3. Kaart

In het geval van een Kaartkunnen we de sleutel of waarde rechtstreeks controleren:

@Test void whenMapContainsKeyElement_thenCheckReturnsTrue () {def map = [a: 'd', b: 'e', ​​c: 'f'] assertTrue (map.containsKey ('a')) assertFalse (map.containsKey ('e') ) assertTrue (map.containsValue ('e'))}

Of gebruik de lidmaatschapsoperator om de overeenkomende sleutel te vinden:

@Test void whenMapContainsKeyElement_thenCheckByMembershipReturnsTrue () {def map = [a: 'd', b: 'e', ​​c: 'f'] assertTrue ('a' in kaart) assertFalse ('f' in kaart)}

Bij gebruik met kaarten moeten we voorzichtig omgaan met de lidmaatschapsoperator, omdat deze operator is een beetje verwarrend om te gebruiken met booleaanse waarden. In plaats van te testen op de aanwezigheid van de sleutel, haalt het onderliggende mechanisme de corresponderende waarde uit de kaart en gewoon cast het naar boolean:

@Test void whenMapContainsFalseBooleanValues_thenCheckReturnsFalse () {def map = [a: true, b: false, c: null] assertTrue (map.containsKey ('b')) assertTrue ('a' op de kaart) assertFalse ('b' op de kaart) assertFalse ('c' in kaart)}

Zoals we in het bovenstaande voorbeeld kunnen zien, is het ook een beetje gevaarlijk om mee te gebruiken nul waarden ofwel om dezelfde reden. Groovy cast beide false en nul naar boolean false.

3. Alle wedstrijden en elke wedstrijd

In de meeste gevallen hebben we te maken met verzamelingen die uit meer complexe objecten bestaan. In deze sectie laten we zien hoe u kunt controleren of de gegeven verzameling ten minste één overeenkomend element bevat of dat alle elementen overeenkomen met een bepaald predikaat.

Laten we beginnen met het definiëren van een eenvoudige klasse die we in onze voorbeelden zullen gebruiken:

class Person {private String voornaam private String achternaam private Geheel getal leeftijd // constructor, getters en setters}

3.1. Lijst / set

Deze keer gebruiken we een eenvoudige lijst met Persoon voorwerpen:

private final personList = [nieuwe persoon ("Regina", "Fitzpatrick", 25), nieuwe persoon ("Abagail", "Ballard", 26), nieuwe persoon ("Lucian", "Walter", 30),]

Zoals we al eerder zeiden, Groovy is een Java-compatibele taal, dus laten we eerst een voorbeeld maken met de Stroom API geïntroduceerd door Java 8:

@Test void givenListOfPerson_whenUsingStreamMatching_thenShouldEvaluateList () {assertTrue (personList.stream (). AnyMatch {it.age> 20}) assertFalse (personList.stream (). AllMatch {it.age <30})}

We kunnen ook de Groovy-methoden gebruiken DefaultGroovyMethods # any en DefaultGroovyMethods # elke die de controle rechtstreeks op de collectie uitvoeren:

@Test ongeldig gegevenListOfPerson_whenUsingCollectionMatching_thenShouldEvaluateList () {assertTrue (personList.any {it.age> 20}) assertFalse (personList.every {it.age <30})}

3.2. Kaart

Laten we beginnen met het definiëren van een Kaart van Persoon objecten in kaart gebracht door Persoon # voornaam:

private final personMap = [Regina: nieuwe persoon ("Regina", "Fitzpatrick", 25), Abagail: nieuwe persoon ("Abagail", "Ballard", 26), Lucian: nieuwe persoon ("Lucian", "Walter", 30)]

We kunnen het evalueren aan de hand van de sleutels, waarden of hele items. Nogmaals, laten we eerst de Stroom API:

@Test ongeldig gegevenMapOfPerson_whenUsingStreamMatching_thenShouldEvaluateMap () {assertTrue (personMap.keySet (). Stream (). AnyMatch {it == "Regina"}) assertFalse (personMap.keySet (). Stream (). AllMatch "{it ==" Regina "}) assertFalse (personMap.keySet (). Stream (). AllMatch" {it ) assertFalse (personMap.values ​​(). stream (). allMatch {it.age <30}) assertTrue (personMap.entrySet (). stream (). anyMatch {it.key == "Abagail" && it.value.lastname == "Ballard"})}

En dan, de Groovy Collection API:

@Test void givenMapOfPerson_whenUsingCollectionMatching_thenShouldEvaluateMap () {assertTrue (personMap.keySet (). Any {it == "Regina"}) assertFalse (personMap.keySet (). Elke {it == "Albert"}) assertap.values ​​(person .elke {it.age firstname == "Abagail" && person.lastname == "Ballard"})}

Zoals we kunnen zien, vervangt Groovy niet alleen de Stroom API bij het manipuleren van kaarten, maar stelt ons ook in staat om rechtstreeks een controle uit te voeren op het Kaart object in plaats van het java.util.Map # entrySet methode.

4. Zoek een of meer elementen in een verzameling

4.1. Lijst / set

We kunnen ook elementen extraheren met predikaten. Laten we beginnen met het bekende Stroom API-aanpak:

@Test ongeldig gegevenListOfPerson_whenUsingStreamFind_thenShouldReturnMatchingElements () {assertTrue (personList.stream (). Filter {it.age> 20} .findAny (). IsPresent ()) assertFalse (personList.stream (). Filter {it.indage> 30}. () .isPresent ()) assertTrue (personList.stream (). filter {it.age> 20} .findAll (). size () == 3) assertTrue (personList.stream (). filter {it.age> 30 } .findAll (). isEmpty ())}

Zoals we kunnen zien, gebruikt het bovenstaande voorbeeld java.util.Optioneel voor het vinden van een enkel element als de Stroom API dwingt die aanpak af.

Aan de andere kant biedt Groovy een veel compactere syntaxis:

@Test ongeldig gegevenListOfPerson_whenUsingCollectionFind_thenShouldReturnMatchingElements () {assertNotNull (personList.find {it.age> 20}) assertNull (personList.find {it.age> 30}) assertTrue (personList.findAll) = {. = 3) assertTrue (personList.findAll {it.age> 30} .isEmpty ())}

Door de API van Groovy te gebruiken, we kunnen het maken van een Stroom en het filteren.

4.2. Kaart

In het geval van een Kaart, er zijn verschillende opties om uit te kiezen. We kunnen elementen vinden tussen sleutels, waarden of volledige invoer. Omdat de eerste twee in feite een Lijst of een Set, in deze sectie laten we alleen een voorbeeld zien van het vinden van items.

Laten we onze personMap van vroeger:

@Test ongeldig gegevenMapOfPerson_whenUsingStreamFind_thenShouldReturnElements () {assertTrue (personMap.entrySet (). Stream () .filter {it.key == "Abagail" && it.value.lastname == "Ballard"} .findAny (). IsPresent (). IsPresent (). assertTrue (personMap.entrySet (). stream () .filter {it.value.age> 20} .findAll (). size () == 3)}

En nogmaals, de vereenvoudigde Groovy-oplossing:

@Test ongeldig gegevenMapOfPerson_whenUsingCollectionFind_thenShouldReturnElements () {assertNotNull (personMap.find {it.key == "Abagail" && it.value.lastname == "Ballard"}) assertTrue (personMap.findAll {it.value.size> 20}. () == 3)}

In dit geval zijn de voordelen zelfs nog groter. We slaan de java.util.Map # entrySet methode en gebruik een sluiting met een functie op de Kaart.

5. Conclusie

In dit artikel hebben we laten zien hoe Groovy vereenvoudigt het controleren op elementen en het vinden ervan in verschillende soorten collecties.

Zoals altijd zijn de volledige codevoorbeelden die in deze tutorial worden gebruikt, beschikbaar op GitHub.