Kako brojati dvostruke elemente u arraylistu

1. Pregled

U ovom ćemo kratkom vodiču pogledati nekoliko različitih načina za brojanje dupliciranih elemenata u ArrayList.

2. Petlja sa Map.put ()

Očekivani rezultat bio bi nam Karta objekt koji sadrži sve elemente s popisa unosa kao ključeve i broj svakog elementa kao vrijednost.

Najjednostavnije rješenje da se to postigne bilo bi prolazak kroz ulazni popis i za svaki element:

  • ako je resultMap sadrži element, brojač povećavamo za 1
  • inače, mi staviti novi unos karte (element, 1) na kartu
javna karta countByClassicalLoop (popis ulaznih popisa) {Map resultMap = new HashMap (); za (T element: inputList) {if (resultMap.containsKey (element)) {resultMap.put (element, resultMap.get (element) + 1L); } else {resultMap.put (element, 1L); }} return resultMap; }

Ova implementacija ima najbolju kompatibilnost, jer radi za sve moderne Java verzije.

Ako nam ne treba kompatibilnost pre-Java 8, možemo dodatno pojednostaviti našu metodu:

javna karta countByForEachLoopWithGetOrDefault (Lista ulaznih popisa) {Map resultMap = new HashMap (); inputList.forEach (e -> resultMap.put (e, resultMap.getOrDefault (e, 0L) + 1L)); povratak resultMap; }

Dalje, kreirajmo ulazni popis za testiranje metode:

privatni popis INPUT_LIST = Lists.list ("očekivati1", "očekivati2", "očekivati2", "očekivati3", "očekivati3", "očekivati3", "očekivati4", "očekivati4", "očekivati4", "očekivati4"); 

A sada provjerimo:

private void verifyResult (Map resultMap) {assertThat (resultMap) .isNotEmpty (). hasSize (4) .containsExactly (entry ("očekivati1", 1L), ulaz ("očekivati2", 2L), ulaz ("očekivati3", 3L) , unos ("očekivati4", 4L)); } 

Ponovno ćemo koristiti ovaj ispitni pojas za ostale pristupe.

3. Petlja sa Map.compute ()

U Javi 8, zgodan izračunati () metoda je uvedena u Karta sučelje. Možemo se poslužiti i ovom metodom:

javna karta countByForEachLoopWithMapCompute (popis ulaznih popisa) {Map resultMap = new HashMap (); inputList.forEach (e -> resultMap.compute (e, (k, v) -> v == null? 1L: v + 1L)); povratak resultMap; }

Obavijest (k, v) -> v == null? 1L: v + 1L je funkcija preslikavanja koja provodi BiFunction sučelje. Za zadani ključ vraća ili trenutnu vrijednost uvećanu za jedan (ako je ključ već prisutan na mapi) ili vraća zadanu vrijednost jednog.

Da bi kod bio čitljiviji, mogli bismo izvući funkciju remapiranja u njezinu varijablu ili je čak uzeti kao ulazni parametar za countByForEachLoopWithMapCompute.

4. Petlja sa Map.merge ()

Prilikom korištenja Map.compute (), moramo se nositi s null vrijednosti eksplicitno - na primjer, ako mapiranje za dati ključ ne postoji. Zbog toga smo implementirali a null provjerite našu funkciju ponovnog mapiranja. To, međutim, ne izgleda lijepo.

Očistimo naš kod dalje uz pomoć Map.merge () metoda:

javna karta countByForEachLoopWithMapMerge (popis ulaznih popisa) {Map resultMap = new HashMap (); inputList.forEach (e -> resultMap.merge (e, 1L, Long :: sum)); povratak resultMap; }

Sada kôd izgleda čisto i sažeto.

Objasnimo kako sjediniti() djela. Ako mapiranje za zadani ključ ne postoji ili je njegova vrijednost null, pridružuje ključ uz navedenu vrijednost. Inače izračunava novu vrijednost pomoću funkcije preslikavanja i ažurira mapiranje u skladu s tim.

Primijetite da smo ovaj put koristili Long :: zbroj kao BiFunction implementacija sučelja.

5. Stream API Collectors.toMap ()

Budući da smo već razgovarali o Javi 8, ne možemo zaboraviti moćni Stream API. Zahvaljujući Stream API-u problem možemo riješiti na vrlo kompaktan način.

The toMap () collector nam pomaže pretvoriti ulazni popis u Karta:

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

The toMap () je prikladan kolektor koji nam može pomoći da tok pretvorimo u drugačiji Karta implementacije.

6. Stream API Collectors.groupingBy () i Kolekcionari.brojenje ()

Osim toMap (), naš problem mogu riješiti druga dva kolektora, grupiranjeBy () i brojanje ():

javna karta countByStreamGroupBy (Popis inputList) {return inputList.stream (). collect (Collectors.groupingBy (k -> k, Collectors.counting ())); }

Pravilna upotreba Java 8 Collectors čini naš kod kompaktnim i lakim za čitanje.

7. Zaključak

U ovom kratkom članku ilustrirali smo razne načine izračuna broja dvostrukih elemenata na popisu.

Ako želite razjasniti sam ArrayList, možete pogledati referentni članak.

Kao i uvijek, cjeloviti izvorni kod dostupan je na GitHub-u.


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