Kort i Groovy

1. Oversigt

Groovy udvider Kort API i Java til give metoder til operationer såsom filtrering, søgning og sortering. Det giver også en forskellige kortfattede måder at oprette og manipulere kort på.

I denne artikel vil vi se på den Groovy måde at arbejde med kort på.

2. Oprettelse af Groovy Korts

Vi kan bruge den bogstavelige syntaks på kortet [k: v] til oprettelse af kort. Dybest set giver det os mulighed for at instantiere et kort og definere poster i en linje.

Et tomt kort kan oprettes ved hjælp af:

def emptyMap = [:]

Tilsvarende kan et kort med værdier instantieres ved hjælp af:

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

Læg mærke til det nøglerne er ikke omgivet af citater.

Og som standard opretter Groovy en forekomst af java.util.LinkedHashMap. Vi kan tilsidesætte denne standardadfærd ved at bruge som operatør.

3. Tilføjelse af emner

Lad os starte med at definere et kort:

def map = [navn: "Jerry"]

Vi kan tilføje en nøgle til kortet:

kort ["alder"] = 42

Men en anden mere Javascript-lignende måde bruger egenskabsnotation (prikoperatøren):

map.city = "New York"

Med andre ord understøtter Groovy adgang til nøgleværdipar på en bønnelignende måde.

Vi kan også bruge variabler i stedet for bogstaver som nøgler, mens vi tilføjer nye elementer til kortet:

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

Først skal vi oprette en ny variabel, der gemmer nøglen hobby. Derefter bruger vi denne variabel, der er lukket i parentes med den bogstavelige syntaks for kortet til at oprette et andet kort.

4. Henter emner

Den bogstavelige syntaks eller egenskabsnotationen kan bruges til at hente varer fra et kort.

For et kort defineret som:

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

Vi kan få den værdi, der svarer til nøglen navn:

assertTrue (kort ["navn"] == "Jerry")

eller

assertTrue (map.name == "Jerry")

5. Fjernelse af emner

Vi kan fjerne enhver post fra et kort baseret på en nøgle ved hjælp af fjerne() metode. Men, nogle gange kan det være nødvendigt at fjerne flere poster fra et kort. Dette kan gøres ved hjælp af minus() metode.

Det minus() metode accepterer en Kort. Og returnerer et nyt Kort efter fjernelse af alle posterne på det givne kort fra det underliggende kort:

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])

Dernæst kan vi også fjerne poster baseret på en betingelse. Dette kan opnås ved hjælp af Fjern alt() metode:

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

Omvendt, for at bevare alle poster, der opfylder en betingelse, kan vi bruge retainAll () metode:

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

6. Iterering gennem poster

Vi kan gentage gennem poster ved hjælp af hver()og eachWithIndex () metoder.

Det hver() metoden giver implicitte parametre som indgang, nøgleog værdi der svarer til strømmen Indgang.

Det eachWithIndex () metode giver også et indeks ud over Indgang. Begge metoder accepterer a Lukning som et argument.

I det næste eksempel gentages vi gennem hvert Indgang. Det Lukning videregivet til hver() metoden henter nøgleværdiparet fra den implicitte parameterindgang og udskriver det:

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

Dernæst bruger vi eachWithIndex () metode til at udskrive det aktuelle indeks sammen med andre værdier:

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

Det er også muligt at spørge nøgle, værdi, og indeks leveres separat:

map.eachWithIndex {nøgle, værdi, i -> println "$ i $ nøgle: $ værdi"}

7. Filtrering

Vi kan bruge find (), findAll () og grep () metoder til at filtrere og søge efter kortindgange baseret på nøgler og værdier.

Lad os starte med at definere et kort til at udføre disse metoder på:

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

Først ser vi på finde() metode, der accepterer en Lukning og returnerer den første Indgang der matcher Lukning tilstand:

assertTrue (map.find {it.value == "New York"}. nøgle == "by")

Tilsvarende findAlle accepterer også en Lukning men returnerer en Kort med alle de nøgleværdipar, der opfylder betingelsen i Lukning:

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

Hvis vi foretrækker at bruge en Liste, men vi kan bruge grep i stedet for findAlle:

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

Vi brugte først grep til at finde poster, der har værdien som New York. Derefter for at demonstrere, er returneringstypen Liste, vi gentager gennem resultatet af grep (). Og for hver Indgang i listen, der er tilgængelig i den implicitte parameter, kontrollerer vi, om det er det forventede resultat.

Dernæst for at finde ud af, om alle elementerne på et kort opfylder en betingelse, vi kan bruge hver som returnerer en boolsk.

Lad os kontrollere, om alle værdier på kortet er af typen Snor:

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

På samme måde kan vi bruge nogen for at afgøre, om nogen elementer på kortet matcher en betingelse:

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

8. Transformering og indsamling

Til tider vil vi måske omdanne posterne på et kort til nye værdier. Bruger indsamle() og collectEntries () metoder er det muligt at omdanne og indsamle poster til en Kollektion eller Kort henholdsvis.

Lad os se på nogle eksempler.

Givet et kort over medarbejder-id'er og medarbejdere:

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

Vi kan indsamle navnene på alle medarbejdere på en liste ved hjælp af indsamle():

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

Dernæst, hvis vi er interesserede i et unikt sæt navne, kan vi specificere samlingen ved at videresende en Kollektion objekt:

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

Hvis vi vil ændre medarbejdernavne på kortet fra små til store bogstaver, kan vi bruge collectEntries. Denne metode returnerer et kort med transformerede værdier:

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

Endelig det er også muligt at bruge indsamle metoder i forbindelse med finde og findAlle metoder for at transformere de filtrerede resultater:

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

Her finder vi først alle medarbejdere i alderen 20-30 og samler dem på et kort.

9. Gruppering

Nogle gange vil vi måske gruppere nogle emner på et kort i underkort baseret på en betingelse.

Det groupBy () metode returnerer et kort over kort. Og hvert kort indeholder nøgleværdipar, der evaluerer til det samme resultat for den givne tilstand:

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 anden måde at oprette underkort på er at bruge subMap (). Det er anderledes i groupBy () i den forstand, at det kun tillader gruppering baseret på tasterne:

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

I dette tilfælde returneres indtastningerne for tasterne 1 og 2 på det nye kort, og alle andre poster kasseres.

10. Sortering

Normalt, når vi sorterer, vil vi måske sortere posterne på et kort baseret på nøgle eller værdi eller begge dele. Groovy giver en sortere() metode, der kan bruges til dette formål.

Givet et kort:

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

Hvis sortering skal foretages på nøglen, skal du bruge no-args sortere() metode, der er baseret på naturlig ordning:

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

Eller brug sorter (Comparator) metode til at give sammenligningslogik:

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

Næste, For at sortere på enten nøgle eller værdier eller begge dele kan vi levere en Lukning tilstand til sortere():

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

11. Konklusion

Vi startede med at se på, hvordan vi kan skabe Korts i Groovy. Dernæst så vi på forskellige måder, hvorpå varer kan tilføjes, hentes og fjernes fra et kort.

Senere dækkede vi metoderne til at udføre almindelige operationer, der leveres ud af kassen i Groovy. De omfattede filtrering, søgning, transformation og sortering.

Som altid kan eksemplerne i artiklen findes på GitHub.