Ú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.