Elemente in Sammlungen in Groovy finden

1. Einleitung

Groovy bietet eine beträchtliche Anzahl von Methoden zur Verbesserung der Kernfunktionen von Java.

In diesem Tutorial zeigen wir, wie Groovy dies tut, wenn er nach einem Element sucht und es in verschiedenen Arten von Sammlungen findet.

2. Testen Sie, ob das Element vorhanden ist

Zunächst konzentrieren wir uns darauf, nur zu testen, ob eine bestimmte Sammlung ein Element enthält.

2.1. Liste

Java selbst bietet verschiedene Möglichkeiten , mit java.util.List nach einem Element in einer Liste zu suchen :

  • Die enthält Methode
  • Die indexOf- Methode

Da Groovy eine Java-kompatible Sprache ist, können wir sie sicher verwenden.

Schauen wir uns ein Beispiel an:

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

Abgesehen davon stellt Groovy den Mitgliedschaftsbetreiber vor:

element in list

Es ist einer von vielen syntaktischen Zuckeroperatoren, die von Groovy bereitgestellt werden. Mit seiner Hilfe können wir unseren Code vereinfachen:

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

2.2. einstellen

Wie bei dem vorherigen Beispiel können wir die Verwendung java.util.Set # enthält Verfahren und die in Operator:

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

2.3. Karte

Im Fall einer Karte können wir entweder den Schlüssel oder den Wert direkt überprüfen:

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

Oder verwenden Sie den Mitgliedschaftsoperator, um den passenden Schlüssel zu finden:

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

Bei Verwendung mit Karten sollten wir den Mitgliedschaftsoperator mit Vorsicht verwenden, da die Verwendung dieses Operators mit booleschen Werten etwas verwirrend ist. Anstatt auf das Vorhandensein des Schlüssels zu testen, ruft der zugrunde liegende Mechanismus den entsprechenden Wert aus der Karte ab und wandelt ihn einfach in einen Booleschen Wert um:

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

Wie wir im obigen Beispiel sehen kann, es ist auch ein bisschen gefährlich mit verwenden Nullwerte entweder aus dem gleichen Grund. Groovy wandelt sowohl false als auch null in boolean false um .

3. Alle Übereinstimmungen und alle Übereinstimmungen

In den meisten Fällen handelt es sich um Sammlungen, die aus komplexeren Objekten bestehen. In diesem Abschnitt wird gezeigt, wie Sie überprüfen können, ob die angegebene Sammlung mindestens ein übereinstimmendes Element enthält oder ob alle Elemente mit einem bestimmten Prädikat übereinstimmen.

Beginnen wir mit der Definition einer einfachen Klasse, die wir in unseren Beispielen verwenden werden:

class Person { private String firstname private String lastname private Integer age // constructor, getters and setters }

3.1. Liste / Set

Dieses Mal verwenden wir eine einfache Liste von Personenobjekten :

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

Wie bereits erwähnt, ist Groovy eine Java-kompatible Sprache. Erstellen wir daher zunächst ein Beispiel mit der von Java 8 eingeführten Stream- API:

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

Wir können auch die Groovy-Methoden DefaultGroovyMethods # any und DefaultGroovyMethods # any verwenden , die die Prüfung direkt für die Sammlung durchführen:

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

3.2. Karte

Beginnen wir mit einer Definition von Karte von Person - Objekten durch kartiert Person # Vorname :

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

Wir können es entweder anhand seiner Schlüssel, Werte oder anhand ganzer Einträge bewerten. Verwenden wir zunächst die Stream- API:

@Test void givenMapOfPerson_whenUsingStreamMatching_thenShouldEvaluateMap() { assertTrue(personMap.keySet().stream().anyMatch {it == "Regina"}) assertFalse(personMap.keySet().stream().allMatch {it == "Albert"}) assertFalse(personMap.values().stream().allMatch {it.age < 30}) assertTrue(personMap.entrySet().stream().anyMatch {it.key == "Abagail" && it.value.lastname == "Ballard"}) }

Und dann die Groovy Collection API:

@Test void givenMapOfPerson_whenUsingCollectionMatching_thenShouldEvaluateMap() { assertTrue(personMap.keySet().any {it == "Regina"}) assertFalse(personMap.keySet().every {it == "Albert"}) assertFalse(personMap.values().every {it.age  firstname == "Abagail" && person.lastname == "Ballard"}) }

Wie wir sehen können, nur Groovy nicht adäquat ersetzt den Stream - API , wenn Karten zu manipulieren , sondern auch ermöglicht es uns , einen Scheck direkt auf dem auszuführen Map - Objekt anstelle dem die Verwendung java.util.Map # entrySet Methode.

4. Suchen Sie ein oder mehrere Elemente in einer Sammlung

4.1. Liste / Set

Wir können Elemente auch mit Prädikaten extrahieren. Beginnen wir mit dem bekannten Stream- API-Ansatz:

@Test void givenListOfPerson_whenUsingStreamFind_thenShouldReturnMatchingElements() { assertTrue(personList.stream().filter {it.age > 20}.findAny().isPresent()) assertFalse(personList.stream().filter {it.age > 30}.findAny().isPresent()) assertTrue(personList.stream().filter {it.age > 20}.findAll().size() == 3) assertTrue(personList.stream().filter {it.age > 30}.findAll().isEmpty()) }

Wie wir sehen können, verwendet das obige Beispiel java.util.Optional, um ein einzelnes Element zu finden, wenn die Stream- API diesen Ansatz erzwingt.

Auf der anderen Seite bietet Groovy eine viel kompaktere Syntax:

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

Mithilfe der Groovy-API können wir das Erstellen und Filtern eines Streams überspringen .

4.2. Map

In the case of a Map, there are several options to choose from. We can find elements amongst keys, values or complete entries. As the first two are basically a List or a Set, in this section we'll only show an example of finding entries.

Let's reuse our personMap from earlier:

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

And again, the simplified Groovy solution:

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

In this case, the benefits are even more significant. We skip the java.util.Map#entrySet method and use a closure with a function provided on the Map.

5. Conclusion

In this article, we presented how Groovy simplifies checking for elements and finding them in several types of collections.

Wie immer sind die vollständigen Codebeispiele, die in diesem Tutorial verwendet werden, auf GitHub verfügbar.