Hogyan lehet megszámolni az ismétlődő elemeket a tömblistában

1. Áttekintés

Ebben a rövid bemutatóban megvizsgálunk néhány módszert a duplikált elemek számlálására Tömb lista.

2. Hurok Map.put ()

Várható eredményünk a Térkép objektum, amely kulcsként tartalmazza a bemeneti lista összes elemét és az egyes elemek számát értékként.

Ennek elérésére a legegyszerűbb megoldás az lenne, ha végignéznénk az input listát és az egyes elemeket:

  • ha a resultMap tartalmazza az elemet, egy számlálót 1-gyel növekszünk
  • különben mi tedd új térképbejegyzés (1. elem) a térképre
public Map countByClassicalLoop (List inputList) {Map resultMap = new HashMap (); for (T elem: inputList) {if (resultMap.containsKey (element)) {resultMap.put (elem, resultMap.get (elem) + 1L); } else {resultMap.put (elem, 1L); }} return resultMap; }

Ennek a megvalósításnak van a legjobb kompatibilitása, mivel az összes modern Java verzióhoz használható.

Ha nincs szükségünk a Java 8 előtti kompatibilitásra, tovább egyszerűsíthetjük a módszerünket:

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

Ezután hozzunk létre egy bemeneti listát a módszer teszteléséhez:

privát lista INPUT_LIST = Lists.list ("várj1", "várj2", "várj2", "várj3", "várj3", "várj3", "várj4", "várj4", "várj4", "várj4"); 

És most ellenőrizzük:

private void VerifyResult (Map resultMap) {assertThat (resultMap) .isNotEmpty (). hasSize (4) .containsExactly (bejegyzés ("várható1", 1L), bejegyzés ("várható2", 2L), bejegyzés ("várakozás3", 3L) , bejegyzés ("várható4", 4L)); } 

Ezt a tesztköteget a továbbiakban is felhasználjuk.

3. Hurok Map.compute ()

A Java 8-ban a praktikus kiszámít() módszert vezették be a Térkép felület. Használhatjuk ezt a módszert is:

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

Értesítés (k, v) -> v == null? 1L: v + 1L az újratervezési függvény, amely a BiFunction felület. Egy adott kulcs esetén vagy megadja az aktuális értékét eggyel növelve (ha a kulcs már szerepel a térképen), vagy pedig az egyik alapértelmezett értékét adja vissza.

A kód olvashatóbbá tétele érdekében kivonhatnánk az újrarendezési függvényt annak változójába, vagy akár a countByForEachLoopWithMapCompute.

4. Hurok Map.merge ()

Használat során Map.compute (), kezelnünk kell a nulla értékek kifejezetten - például, ha egy adott kulcshoz nincs hozzárendelés. Ezért hajtottuk végre a nulla ellenőrizze az újratervezési funkciót. Ez azonban nem tűnik szépnek.

Tisztítsuk tovább a kódunkat a segítségével Map.merge () módszer:

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

Most a kód tiszta és tömörnek tűnik.

Magyarázzuk el, hogyan összeolvad() művek. Ha egy adott kulcs leképezése nem létezik, vagy annak értéke van nulla, társítja a kulcsot a megadott értékhez. Ellenkező esetben új értéket számol ki az újratervezési funkció segítségével, és ennek megfelelően frissíti a leképezést.

Vegyük észre, hogy ezúttal használtuk Hosszú :: összeg mint a BiFunction interfész megvalósítása.

5. Stream API Collectors.toMap ()

Mivel már beszéltünk a Java 8-ról, nem feledkezhetünk meg az erőteljes Stream API-ról sem. A Stream API-nak köszönhetően nagyon kompakt módon tudjuk megoldani a problémát.

A térképre() A gyűjtő segít abban, hogy a bemeneti listát a Térkép:

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

A térképre() egy kényelmes gyűjtő, amely segíthet abban, hogy a folyamot különbözővé alakítsuk Térkép megvalósítások.

6. Stream API Collectors.groupingBy () és Collectors.counting ()

Kivéve a térképre(), problémánkat két másik gyűjtő is megoldhatja, groupingBy () és számolás():

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

A Java 8 Collectors megfelelő használata kompaktvá és könnyen olvashatóvá teszi kódunkat.

7. Következtetés

Ebben a rövid cikkben különféle módszereket szemléltettünk egy lista duplikált elemeinek kiszámításához.

Ha szeretné magába foglalni az ArrayList, megnézheti a referencia cikket.

Mint mindig, a teljes forráskód elérhető a GitHubon.