Kart i Groovy

1. Oversikt

Groovy utvider Kart API i Java til gi metoder for operasjoner som filtrering, søk og sortering. Det gir også en en rekke kortfattede måter å lage og manipulere kart på.

I denne artikkelen vil vi se på Groovy-måten å jobbe med kart på.

2. Opprette Groovy Karts

Vi kan bruke bokstavelig syntaks [k: v] for å lage kart. I utgangspunktet tillater det oss å instantiere et kart og definere oppføringer i en linje.

Et tomt kart kan opprettes ved hjelp av:

def emptyMap = [:]

På samme måte kan et kart med verdier instantieres ved hjelp av:

def map = [navn: "Jerry", alder: 42, by: "New York"]

Legg merke til det nøklene er ikke omgitt av anførselstegn.

Og som standard oppretter Groovy en forekomst av java.util.LinkedHashMap. Vi kan overstyre denne standardadferden ved å bruke som operatør.

3. Legge til elementer

La oss starte med å definere et kart:

def map = [navn: "Jerry"]

Vi kan legge til en nøkkel til kartet:

map ["age"] = 42

Men en annen mer Javascript-lignende måte er å bruke eiendomsnotasjon (prikkoperatøren):

map.city = "New York"

Med andre ord støtter Groovy tilgang til nøkkelverdipar på en bønnelignende måte.

Vi kan også bruke variabler i stedet for bokstaver som nøkler mens vi legger til nye elementer på kartet:

def hobbyLiteral = "hobby" def hobbyMap = [(hobbyLiteral): "Singing"] map.putAll (hobbyMap) assertTrue (hobbyMap.hobby == "Singing") assertTrue (hobbyMap [hobbyLiteral] == "Singing")

Først må vi lage en ny variabel som lagrer nøkkelen Hobby. Deretter bruker vi denne variabelen innelukket i parentes med den bokstavelige syntaksen for kartet for å lage et nytt kart.

4. Henter gjenstander

Bokstavsyntaksen eller eiendomsnotasjonen kan brukes til å hente elementer fra et kart.

For et kart definert som:

def map = [navn: "Jerry", alder: 42, by: "New York", hobby: "Singing"]

Vi kan få verdien som tilsvarer nøkkelen Navn:

assertTrue (map ["name"] == "Jerry")

eller

assertTrue (map.name == "Jerry")

5. Fjerne gjenstander

Vi kan fjerne alle oppføringer fra et kart basert på en nøkkel ved hjelp av fjerne() metode. Men, noen ganger kan det hende vi må fjerne flere oppføringer fra et kart. Dette kan gjøres ved hjelp av minus() metode.

De minus() metoden godtar en Kart. Og returnerer en ny Kart etter å ha fjernet alle oppføringene på det gitte kartet fra det underliggende kartet:

def map = [1:20, a: 30, 2:42, 4:34, ba: 67, 6:39, 7:49] def minusMap = map.minus ([2:42, 4:34]); assertTrue (minusMap == [1:20, a: 30, ba: 67, 6:39, 7:49])

Deretter kan vi også fjerne oppføringer basert på en tilstand. Dette kan oppnås ved hjelp av Fjern alle() metode:

minusMap.removeAll {it -> it.key instance of String} assertTrue (minusMap == [1:20, 6:39, 7:49])

Omvendt, for å beholde alle oppføringer som tilfredsstiller en betingelse, kan vi bruke beholdeAll () metode:

minusMap.retainAll {it -> it.value% 2 == 0} assertTrue (minusMap == [1:20])

6. Iterere gjennom oppføringer

Vi kan gjenta gjennom oppføringer ved hjelp av Hver()og eachWithIndex () metoder.

De Hver() metoden gir implisitte parametere som inngang, nøkkel, og verdi som tilsvarer strømmen Inngang.

De eachWithIndex () metoden gir også en indeks i tillegg til Inngang. Begge metodene aksepterer a Lukking som argument.

I neste eksempel gjentar vi gjennom hvert Inngang. De Lukking overført til Hver() metoden henter nøkkelverdiparet fra den implisitte parameteroppføringen og skriver den ut:

map.each {entry -> println "$ entry.key: $ entry.value"}

Deretter bruker vi eachWithIndex () metode for å skrive ut gjeldende indeks sammen med andre verdier:

map.eachWithIndex {entry, i -> println "$ i $ entry.key: $ entry.value"}

Det er også mulig å spørre nøkkel, verdi, og indeks leveres separat:

map.eachWithIndex {key, value, i -> println "$ i $ key: $ value"}

7. Filtrering

Vi kan bruke finn (), finnAll () og grep () metoder for å filtrere og søke etter kartoppføringer basert på nøkler og verdier.

La oss starte med å definere et kart for å utføre disse metodene på:

def map = [navn: "Jerry", alder: 42, by: "New York", hobby: "Singing"]

Først ser vi på finne() metode som godtar en Lukking og returnerer den første Inngang som samsvarer med Lukking tilstand:

assertTrue (map.find {it.value == "New York"}. key == "city")

På samme måte, finn alle aksepterer også a Lukking men returnerer a Kart med alle nøkkelverdiparene som tilfredsstiller betingelsen i Lukking:

assertTrue (map.findAll {it.value == "New York"} == [by: "New York"])

Hvis vi foretrekker å bruke en Liste, skjønt, vi kan bruke grep i stedet for finn alle:

map.grep {it.value == "New York"}. hver {it -> assertTrue (it.key == "city" && it.value == "New York")}

Vi brukte først grep for å finne oppføringer som har verdien som New York. Så, for å demonstrere returtypen er Liste, vi gjentar gjennom resultatet av grep (). Og for hver Inngang i listen som er tilgjengelig i den implisitte parameteren, sjekker vi om det er det forventede resultatet.

Deretter for å finne ut om alle elementene på et kart tilfredsstiller en tilstand vi kan bruke hver som returnerer a boolsk.

La oss sjekke om alle verdiene på kartet er av type String:

assertTrue (map.every {it -> it.value instanceof String} == false)

På samme måte kan vi bruke noen for å avgjøre om noen elementer på kartet samsvarer med en tilstand:

assertTrue (map.any {it -> it.value instance of String} == true)

8. Transforming and Collecting

Noen ganger vil vi kanskje transformere oppføringene i et kart til nye verdier. Bruker samle inn() og collectEntries () metoder er det mulig å transformere og samle oppføringer til en Samling eller Kart henholdsvis.

La oss se på noen eksempler.

Gitt et kart over ansatt-ID og ansatte:

def map = [1: [name: "Jerry", age: 42, city: "New York"], 2: [name: "Long", age: 25, city: "New York"], 3: [name : "Dustin", alder: 29, by: "New York"], 4: [navn: "Dustin", alder: 34, by: "New York"]]

Vi kan samle navnene på alle ansatte i en liste ved hjelp av samle inn():

def names = map.collect {entry -> entry.value.name} assertTrue (names == ["Jerry", "Long", "Dustin", "Dustin"])

Deretter, hvis vi er interessert i et unikt sett med navn, kan vi spesifisere samlingen ved å sende en Samling gjenstand:

def unikeNames = map.collect ([] som HashSet) {entry -> entry.value.name} assertTrue (uniqueNames == ["Jerry", "Long", "Dustin"] som sett)

Hvis vi vil endre ansattnavnene på kartet fra små til store bokstaver, kan vi bruke collectEntries. Denne metoden returnerer et kart over transformerte verdier:

def idNames = map.collectEntries {key, value -> [key, value.name]} assertTrue (idNames == [1: "Jerry", 2: "Long", 3: "Dustin", 4: "Dustin"] )

Til slutt, det er også mulig å bruke samle inn metoder i forbindelse med finne og finn alle metoder for å transformere de filtrerte resultatene:

def below30Names = map.findAll {it.value.age value.name} assertTrue (below30Names == ["Long", "Dustin"])

Her finner vi først alle ansatte i alderen 20-30 og samler dem inn på et kart.

9. Gruppering

Noen ganger kan det være lurt å gruppere noen elementer på et kart i underkart basert på en tilstand.

De gruppe av() metoden returnerer et kart med kart. Og hvert kart inneholder nøkkelverdipar som evalueres til samme resultat for den gitte tilstanden:

def map = [1:20, 2: 40, 3: 11, 4: 93] def subMap = map.groupBy {it.value% 2} assertTrue (subMap == [0: [1:20, 2:40] , 1: [3:11, 4:93]])

En annen måte å lage underkart på er å bruke subMap (). Det er annerledes i gruppe av() i den forstand at det bare tillater gruppering basert på tastene:

def keySubMap = map.subMap ([1,2]) assertTrue (keySubMap == [1:20, 2:40])

I dette tilfellet returneres oppføringene for tastene 1 og 2 i det nye kartet, og alle andre oppføringer blir kastet.

10. Sortering

Vanligvis, når vi sorterer, kan det være lurt å sortere oppføringene på et kart basert på nøkkel eller verdi eller begge deler. Groovy gir en sortere() metode som kan brukes til dette formålet.

Gitt et kart:

def map = [ab: 20, a: 40, cb: 11, ba: 93]

Hvis sortering må gjøres på nøkkel, bruk no-args sortere() metode som er basert på naturlig bestilling:

def naturligOrderedMap = map.sort () assertTrue ([a: 40, ab: 20, ba: 93, cb: 11] == naturligOrderedMap)

Eller bruk sorter (Comparator) metode for å gi sammenligningslogikk:

def compSortedMap = map.sort ({k1, k2 -> k1 k2} som Comparator) assertTrue ([a: 40, ab: 20, ba: 93, cb: 11] == compSortedMap)

Neste, for å sortere på enten nøkkel eller verdier eller begge deler, kan vi levere en Lukking tilstand til sortere():

def cloSortedMap = map.sort ({it1, it2 -> it1.value it1.value}) assertTrue ([cb: 11, ab: 20, a: 40, ba: 93] == cloSortedMap)

11. Konklusjon

Vi startet med å se på hvordan vi kan skape Karts i Groovy. Deretter så vi på forskjellige måter elementene kan legges til, hentes og fjernes fra et kart.

Senere dekket vi metodene for å utføre vanlige operasjoner som leveres ut av esken i Groovy. De inkluderte filtrering, søk, transformering og sortering.

Som alltid kan eksemplene som er dekket i artikkelen finnes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found