Hvordan telle dupliserte elementer i matriselisten

1. Oversikt

I denne korte opplæringen vil vi se på noen forskjellige måter å telle de dupliserte elementene i ArrayList.

2. Sløyfe med Map.put ()

Vårt forventede resultat ville være et Kart objekt, som inneholder alle elementene fra inngangslisten som nøkler og tellingen av hvert element som verdi.

Den enkleste løsningen for å oppnå dette vil være å gå gjennom inngangslisten og for hvert element:

  • hvis resultMap inneholder elementet, øker vi en teller med 1
  • ellers, vi sette en ny kartoppføring (element, 1) til kartet
public Map countByClassicalLoop (List inputList) {Map resultMap = new HashMap (); for (T element: inputList) {if (resultMap.containsKey (element)) {resultMap.put (element, resultMap.get (element) + 1L); } annet {resultMap.put (element, 1L); }} return resultMap; }

Denne implementeringen har best kompatibilitet, siden den fungerer for alle moderne Java-versjoner.

Hvis vi ikke trenger pre-Java 8-kompatibilitet, kan vi forenkle metoden vår ytterligere:

public Map countByForEachLoopWithGetOrDefault (List inputList) {Map resultMap = new HashMap (); inputList.forEach (e -> resultMap.put (e, resultMap.getOrDefault (e, 0L) + 1L)); return resultMap; }

La oss deretter lage en inngangsliste for å teste metoden:

privat liste INPUT_LIST = Lists.list ("expect1", "expect2", "expect2", "expect3", "expect3", "expect3", "expect4", "expect4", "expect4", "expect4"); 

Og la oss nå bekrefte det:

private void verifyResult (Map resultMap) {assertThat (resultMap) .isNotEmpty (). hasSize (4) .containsExactly (entry ("expect1", 1L), entry ("expect2", 2L), entry ("expect3", 3L) , oppføring ("expect4", 4L)); } 

Vi bruker denne testselen på nytt for resten av tilnærmingen vår.

3. Sløyfe med Map.compute ()

I Java 8, det praktiske beregne () metoden har blitt introdusert for Kart grensesnitt. Vi kan også bruke denne metoden:

public Map countByForEachLoopWithMapCompute (List inputList) {Map resultMap = new HashMap (); inputList.forEach (e -> resultMap.compute (e, (k, v) -> v == null? 1L: v + 1L)); return resultMap; }

Legge merke til (k, v) -> v == null? 1L: v + 1L er remapping-funksjonen som implementerer BiFunction grensesnitt. For en gitt nøkkel returnerer den enten gjeldende verdi inkrementert av en (hvis nøkkelen allerede er tilstede på kartet) eller returnerer standardverdien for en.

For å gjøre koden mer lesbar, vi kunne trekke om kartleggingsfunksjonen til variabelen eller til og med ta den som inndataparameter for countByForEachLoopWithMapCompute.

4. Sløyfe med Map.merge ()

Når du bruker Map.compute (), vi må håndtere null verdier eksplisitt - for eksempel hvis en kartlegging for en gitt nøkkel ikke eksisterer. Dette er grunnen til at vi har implementert en null sjekk inn vår remapping-funksjon. Dette ser imidlertid ikke pent ut.

La oss rydde opp koden vår videre ved hjelp av Map.merge () metode:

public Map countByForEachLoopWithMapMerge (List inputList) {Map resultMap = new HashMap (); inputList.forEach (e -> resultMap.merge (e, 1L, Long :: sum)); return resultMap; }

Nå ser koden ren og konsis ut.

La oss forklare hvordan slå sammen() virker. Hvis kartleggingen for en gitt nøkkel ikke eksisterer, eller hvis verdien er null, den knytter nøkkelen til den oppgitte verdien. Ellers beregner den en ny verdi ved hjelp av remapping-funksjonen og oppdaterer kartleggingen deretter.

Legg merke til at denne gangen vi brukte Lang :: sum som BiFunction grensesnittimplementering.

5. Stream API Collectors.toMap ()

Siden vi allerede har snakket om Java 8, kan vi ikke glemme den kraftige Stream API. Takket være Stream API kan vi løse problemet på en veldig kompakt måte.

De å kartlegge() samler hjelper oss med å konvertere inngangslisten til en Kart:

public Map countByStreamToMap (List inputList) {return inputList.stream (). collect (Collectors.toMap (Function.identity (), v -> 1L, Long :: sum)); }

De å kartlegge() er en praktisk samler, som kan hjelpe oss med å transformere strømmen til annerledes Kart implementeringer.

6. Stream API Collectors.groupingBy () og Collectors.counting ()

Bortsett fra å kartlegge(), vårt problem kan løses av to andre samlere, gruppering av () og teller ():

public Map countByStreamGroupBy (List inputList) {return inputList.stream (). collect (Collectors.groupingBy (k -> k, Collectors.counting ())); }

Riktig bruk av Java 8 Collectors gjør koden vår kompakt og lett å lese.

7. Konklusjon

I denne raske artikkelen illustrerte vi forskjellige måter å beregne antall dupliserte elementer i en liste.

Hvis du ønsker å pusse opp selve ArrayList, kan du sjekke ut referanseartikkelen.

Som alltid er den komplette kildekoden tilgjengelig på GitHub.


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