CodeGym /Java blog /Véletlen /Hagyd abba a hurkok írását! A 10 legjobb gyakorlat a gyűj...
John Squirrels
Szint
San Francisco

Hagyd abba a hurkok írását! A 10 legjobb gyakorlat a gyűjteményekkel való munkavégzéshez Java 8-ban

Megjelent a csoportban
Hagyd abba a hurkok írását!  A 10 legjobb gyakorlat a gyűjteményekkel való munkához Java 8-ban – 1 Mint tudod, szokásaink a második természetből fakadnak. És ha megszoktad az írást for (int i = 0; i <......), egyik részed sem akarja, hogy újra meg kelljen tanulnod ezt a konstrukciót (főleg, hogy elég egyszerű és érthető). A ciklusokat azonban gyakran ismételten használják ugyanazon alapműveletek végrehajtására, és az ismétlés olyan dolog, amitől nagyon szeretnénk megszabadulni. A Java 8 segítségével az Oracle úgy döntött, hogy segít nekünk ebben. Az alábbiakban felsoroljuk a 10 legjobb gyűjtési módszert, amelyek rengeteg időt és kódot takarítanak meg.

1. Iterable.forEach(fogyasztói <? Super T> akció)

A név magáért beszél. Megismétli az argumentumként átadott gyűjteményt, és minden elemére végrehajtja a lambda műveletet.

List <Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
 numbers.forEach(s -> System.out.print(s + " "));

1 2 3 4 5 6 7

2. Collection.removeIf(Predikátum<? szuper E> szűrő)

Itt megint nincs semmi nehéz. A metódus ismétlődik a gyűjteményben, és eltávolítja a megfelelő elemeket filter.

 List <Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
 numbers.removeIf(s -> s > 5);
 numbers.forEach(s -> System.out.print(s + " "));
Egy sorban eltávolítunk a listából minden 5-nél nagyobb számot.

3. Map.forEach(BiConsumer <? Super K, ? Super V> akció)

A forEachmetódus nem csak az interfészt megvalósító osztályoknál működik Collection, hanem a Map.

 Map <String, String> books = new HashMap<>();
 books.put("War and Peace", "Leo Tolstoy");
 books.put("Crime and Punishment", "Fyodor Dostoevsky");
 books.put("Thinking in Java", "Bruce Eckel");
 books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
 books.put("The Lord of the Rings", "John Tolkien");
 books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));

Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien

4. Map.compute (K kulcs, BiFunction<? Super K,? Super V,? Extends V> remappingFunction)

Kicsit ijesztőbbnek tűnik, de valójában egyszerűnek, mint az összes korábbi. Ez a metódus keya végrehajtás eredményével egyenlő értékre állítja be mappingFunction. Például:

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
 
books.compute("Thinking in Java", (a,b) -> b + ", cool dude");
System.out.println("_______________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));

Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
_______________________
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel, cool dude
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
A "Thinking in Java" szerzője határozottan menő! :)

5. Map.computeIfAbsent(K kulcs, függvény <? szuper K, ? kiterjeszti V> leképezési függvény)

Ez a metódus új elemet ad a -hoz Map, de csak akkor, ha még nem rendelkezik az adott kulccsal rendelkező elemmel. A hozzárendelt érték a végrehajtás eredménye lesz mappingFunction. Ha már létezik egy kulcsos elem, az nem kerül felülírásra. Egyszerűen úgy marad, ahogy van. Térjünk vissza könyveinkhez, és próbáljunk ki egy új módszert:

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.computeIfAbsent("Harry Potter and the Prisoner of Azkaban", b -> getHarryPotterAuthor());
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
Íme a miénk mappingFunction:

public static String getHarryPotterAuthor() {
        return "Joanne Rowling";
    }
És itt az új könyv:

Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Harry Potter and the Prisoner of Azkaban. Author: Joanne Rowling
Book title: Lord of the Rings. Author: John Tolkien

6. Map.computeIfPresent(K kulcs, BiFunction<? szuper K, ? szuper V, ? kiterjeszti V> remappingFunction)

Itt ugyanaz az elv, mint a Map.compute(), de a számításokat csak akkor hajtjuk végre, ha keymár létezik egy elem a -val.

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.computeIfPresent("Eugene Onegin", (a,b) -> b = "Alexander Pushkin");
System.out.println("_________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
books.computeIfPresent("The Brothers Karamazov", (a,b) -> b = "Alexander Pushkin");
System.out.println("_________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
A függvény első hívása nem változott, mivel a mi kínálatunkban nincs "Jevgene Onegin" könyv Map. De a második felhívásban a program megváltoztatta a „Karamazov testvérek” című könyv szerzőjét Alekszandr Puskinra. Kimenet:

_________________
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
 _________________
Book title: The Brothers Karamazov. Author: Alexander Pushkin
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien

7. Map.getOrDefault (objektumkulcs, V alapértelmezett érték)

Ez a metódus a következőnek megfelelő értéket adja vissza key. Ha a kulcs nem létezik, akkor az alapértelmezett értéket adja vissza.

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
String igor = books.getOrDefault("The Tale of Igor's Campaign", "Unknown author");
System.out.println(igor);
Ez nagyon kényelmes:

Unknown author

8. Map.merge(K kulcs, V érték, BiFunction<? szuper V, ? szuper V, ? kiterjeszti V> remappingFunction)

Meg sem próbáltam kiszámolni, hogy ez a módszer hány sornyi kódot takarít meg.
  1. Ha keynem létezik a kulcsodban Map, vagy a valuefor this key az null, akkor a metódus hozzáadja az átadott key-valuepárt a kulcshoz Map.
  2. Ha keylétezik és a value != null, akkor a metódus megváltoztatja az értékét a végrehajtás eredményére remappingFunction.
  3. Ha remappingFunctionvisszatér null, akkor a keyrendszer eltávolítja a gyűjteményből.

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.merge("Thinking in Java", "Bruce Eckel", (a, b) -> b + " and some coauthor");
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));
Kimenet:

Title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Title: Thinking in Java. Author: Bruce Eckel and some coauthor
Title: Crime and Punishment. Author: Fyodor Dostoevsky
Title: War and Peace. Author: Leo Tolstoy
Title: Lord of the Rings. Author: John Tolkien
*bocs, Bruce*

9. Map.putIfAbsent(K kulcs, V érték)

Korábban egy pár hozzáadásához a -hoz Map, ha még nem volt ott, a következőket kellett tennie:

Map <String, String> map = new HashMap<>();
if (map.get("Lord of the Rings") == null)
    map.put("Lord of the Rings", "John Tolkien");
Most minden sokkal könnyebbé vált:

Map<String, String> map = new HashMap<>();
map.putIfAbsent("Lord of the Rings", "John Tolkien");

10. Map.replace és Map.replaceAll()

Végül, de nem utolsó sorban.
  1. Map.replace(K key, V newValue)lecseréli keyértékét -ra newValue, ha létezik ilyen kulcs. Ha nem, akkor nem történik semmi.
  2. Map.replace(K key, V oldValue, V newValue)ugyanezt teszi, de csak akkor, ha a jelenlegi értéke keyegyenlő oldValue.
  3. Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)mindegyiket valuea függvény eredményével helyettesíti.
Például:

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.replace("The Brothers Karamazov", "Bruce Eckel", "John Tolkien");
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));

Title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Title: Thinking in Java. Author: Bruce Eckel
Title: Crime and Punishment. Author: Fyodor Dostoevsky
Title: War and Peace. Author: Leo Tolstoy
Title: Lord of the Rings. Author: John Tolkien
Nem sikerült! A „The Brothers Karamazov” kulcs jelenlegi értéke „Fjodor Dosztojevszkij”, nem „Bruce Eckel”, tehát semmi sem változott.

Map  books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.replaceAll((a,b) -> getCoolAuthor());
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));

public static String getCoolAuthor() {
        return "Cool author";
     }

Title: The Brothers Karamazov. Author: Cool author
Title: Thinking in Java. Author: Cool author
Title: Crime and Punishment. Author: Cool author
Title: War and Peace. Author: Cool author
Title: Lord of the Rings. Author: Cool author
MapKönnyen , bonyolult konstrukciók nélkül változtattuk meg az egész értékeit ! PS Megszokni az újat mindig nehéz, de ezek a változtatások nagyon jók. Mindenesetre a kódom egyes részei határozottan kevésbé hasonlítanak a spagettire, mint korábban :) Sok sikert a tanuláshoz!
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION