Útmutató a Java 8 forEach-hoz

1. Áttekintés

A Java 8-ban bevezetett az egyes ciklus biztosítja a programozók számára egy új, tömör és érdekes módszer a gyűjtemény ismétléséhez.

Ebben a cikkben megtudjuk, hogyan kell használni az egyes a gyűjteményekkel, milyen érvre van szükség, és miben különbözik ez a hurok a továbbfejlesztettől for-loop.

Ha bővítenie kell a Java 8 néhány fogalmát, rendelkezésünkre áll egy cikkgyűjtemény, amely segítségére lehet.

2. Alapjai az egyes

Java-ban az Gyűjtemény interfész rendelkezik Iterálható mint szuper interfész - és a Java 8-tól kezdve ez a felület új API-val rendelkezik:

void forEach (Fogyasztói tevékenység)

Egyszerűen fogalmazva a az egyes statisztikák azt „Addig hajtja végre az adott műveletet az Iterable egyes elemein, amíg az összes elem feldolgozásra nem kerül, vagy a művelet kivételt nem eredményez.”

És így, azzal az egyes, iterálhatunk egy gyűjtemény felett, és minden elemhez elvégezhetünk egy adott műveletet, mint bármely más elemet Iterátor.

Például a for-loop iterálás és nyomtatás változata a Gyűjtemény nak,-nek Húrok:

for (Karakterlánc neve: nevek) {System.out.println (név); }

Írhatjuk ezt a az egyes mint:

names.forEach (név -> {System.out.println (név);});

3. A az egyes Módszer

Használunk az egyes hogy iteráljon egy gyűjteményen, és bizonyos elemeket hajtson végre az egyes elemeken. Az elvégzendő művelet egy osztályban található, amely végrehajtja a Fogyasztó interfész és továbbításra kerül az egyes érvként.

A Fogyasztó interfész funkcionális interfész (interfész egyetlen elvont módszerrel). Elfogad egy bemenetet, és nem ad eredményt.

Itt van a meghatározás:

@FunctionalInterface nyilvános felület Fogyasztó {void accept (T t); }

Ezért bármilyen megvalósítás, például egy olyan felhasználó, amely egyszerűen kinyomtatja a Húr:

Consumer printConsumer = new Consumer () {public void accept (String name) {System.out.println (név); }; };

átadható az egyes érvként:

nevek.forEach (printConsumer);

De ez nem az egyetlen módja a cselekvés létrehozásának a fogyasztón keresztül és felhasználásával az egyes API.

Lássuk a 3 legnépszerűbb módszert, amellyel használni fogjuk az egyes módszer:

3.1. Névtelen Fogyasztó Végrehajtás

Pillanatnyilag megvalósíthatjuk a Fogyasztó felület egy névtelen osztály használatával, majd argumentumként alkalmazza a az egyes módszer:

Consumer printConsumer = new Consumer () {public void accept (String name) {System.out.println (név); }}; nevek.forEach (printConsumer);

Ez jól működik, de ha a fenti példánál elemezzük, látni fogjuk, hogy a tényleges használandó rész a kód belsejében található kód elfogad() módszer.

Bár a lambda kifejezések ma már a szokásos és egyszerűbb módszer erre, mégis érdemes tudni, hogyan kell végrehajtani Fogyasztó felület.

3.2. A Lambda kifejezés

A Java 8 funkcionális interfészek legfőbb előnye, hogy a Lambda kifejezéseket felhasználhatjuk azok példányosítására, és elkerülhetjük a terjedelmes, névtelen osztálymegvalósításokat.

Mint Fogyasztó Az interfész funkcionális interfész, a Lambda-ban kifejezhetjük:

(argumentum) -> {// törzs}

Ezért a mi printConsumer leegyszerűsíti:

név -> System.out.println (név)

És átadhatjuk az egyes mint:

names.forEach (név -> System.out.println (név));

A Lambda kifejezések bevezetése óta a Java 8-ban valószínűleg ez a leggyakoribb módszer a az egyes módszer.

A lambdáknak nagyon is valóságos a tanulási görbéjük, így ha kezdi, ez az írás áttekinti az új nyelvi funkció használatának néhány jó gyakorlatát.

3.3. A módszer referenciája

Használhatunk metódus referencia szintaxist a normál Lambda szintaxis helyett, ahol már létezik metódus egy művelet végrehajtására az osztályon:

names.forEach (System.out :: println);

4. Munka az egyes

4.1. Egy gyűjtemény felett iterálva

Bármilyen típusú iterálható Gyűjtemény - lista, készlet, sor stb. ugyanazzal a szintaxissal rendelkezik a használathoz az egyes.

Ezért, mint már láttuk, a lista elemeinek ismétlése:

Listanevek = Arrays.asList ("Larry", "Steve", "James"); names.forEach (System.out :: println);

Hasonlóan egy készlethez:

Set uniqueNames = új HashSet (Arrays.asList ("Larry", "Steve", "James")); egyediNevek.forEach (System.out :: println);

Vagy mondjuk a Sor ami szintén a Gyűjtemény:

Queue namesQueue = new ArrayDeque (Arrays.asList ("Larry", "Steve", "James")); namesQueue.forEach (System.out :: println);

4.2. Iterálás egy térkép felett - a térképek használata az egyes

A térképek nem Iterálható, de megteszik megadják a saját változatukat az egyes hogy elfogadja a BiConsumer.

A BiConsumer helyett vezették be Fogyasztó az Iterable-ben az egyes hogy egy műveletet végre lehessen hajtani az a kulcsán és értékén egyaránt Térkép egyidejűleg.

Hozzunk létre egy Térkép bejegyzések:

Térképnévtérkép = new HashMap (); namesMap.put (1, "Larry"); namesMap.put (2, "Steve"); namesMap.put (3, "James");

Ezután ismételjük át nevekTérkép a Map's segítségével az egyes:

namesMap.forEach ((kulcs, érték) -> System.out.println (kulcs + "" + érték));

Amint itt láthatjuk, a BiConsumer:

(kulcs, érték) -> System.out.println (kulcs + "" + érték)

hogy ismétli a Térkép.

4.3. Iteráló Több mint a Térkép - iterálással entrySet

Ismételhetjük a EntrySet a Térkép az Iterable's használatával az egyes.

Mivel a bejegyzések Térkép tárolják a Készlet hívott EntrySet, iterálhatjuk, hogy a az egyes:

namesMap.entrySet (). forEach (bejegyzés -> System.out.println (entry.getKey () + "" + entry.getValue ()));

5. Foreach vs For-Loop

Egyszerű szempontból mindkét hurok ugyanazt a funkcionalitást biztosítja - végigvezetve a gyűjtemény elemeit.

A fő különbség kettejük között az, hogy különböző iterátorok - a továbbfejlesztett for-loop külső iterátor, míg az új az egyes módszer belső.

5.1. Belső iterátor - az egyes

Ez a típusú iterátor kezeli az iterációt a háttérben, és hagyja a programozót, hogy csak kódolja, mit kell tenni a gyűjtemény elemeivel.

Az iterátor ehelyett kezeli az iterációt, és gondoskodik az elemek egyesével történő feldolgozásáról.

Lássunk egy példát egy belső iterátorra:

names.forEach (név -> System.out.println (név));

Ban,-ben az egyes A fenti módszerrel láthatjuk, hogy a megadott argumentum lambda kifejezés. Ez azt jelenti, hogy a módszert csak ismerni kell mit kell tenni és az iterálás minden munkájáról belsőleg gondoskodni kell.

5.2. Külső iterátor - for-loop

A külső iterátorok keverik a mit és a hogyan a ciklust meg kell tenni.

Felsorolás, Iterátorok és fokozott for-loop mind külső iterátorok (ne feledje a módszereket iterátor (),következő() vagy hasNext () ? ). Mindezekben az iterátorokban az a feladatunk, hogy meghatározzuk az iterációk végrehajtásának módját.

Fontolja meg ezt a megszokott ciklust:

for (Karakterlánc neve: nevek) {System.out.println (név); }

Bár nem kifejezetten hivatkozunk hasNext () vagy következő() metódusokat a lista felett, az alapul szolgáló kód, amely ezt az iterációs munkát elvégzi, ezeket a módszereket használja. Ez azt jelenti, hogy ezeknek a műveleteknek a bonyolultsága rejtve van a programozó előtt, de még mindig létezik.

Ellentétben egy belső iterátorral, amelyben a gyűjtemény maga végzi az iterációt, itt olyan külső kódra van szükségünk, amely minden elemet kivesz a gyűjteményből.

6. Következtetés

Ebben a cikkben megmutattuk, hogy a az egyes hurok kényelmesebb, mint a normál for-loop.

Azt is láttuk, hogy a az egyes A módszer működik, és milyen megvalósítás érhető el érvként annak érdekében, hogy a gyűjtemény egyes elemein műveletet hajtson végre.

Végül az ebben a cikkben használt összes kivonat elérhető a Github adattárunkban.