CodeGym /Java blog /Tilfældig /Stop med at skrive loops! Top 10 bedste praksis for at ar...
John Squirrels
Niveau
San Francisco

Stop med at skrive loops! Top 10 bedste praksis for at arbejde med samlinger i Java 8

Udgivet i gruppen
Stop med at skrive loops!  Top 10 bedste praksis for at arbejde med samlinger i Java 8 - 1 Som du ved, er vores vaner anden natur. Og når du først har vænnet dig til at skrive for (int i = 0; i <......), er der ingen del af dig, der ønsker at skulle genlære denne konstruktion (især da den er ret enkel og forståelig). Dog bliver loops ofte brugt gentagne gange til at udføre de samme grundlæggende operationer, og gentagelse er noget, vi meget gerne vil slippe for. Med Java 8 har Oracle besluttet at hjælpe os med dette. Nedenfor er de 10 bedste indsamlingsmetoder, der vil spare dig for masser af tid og kode.

1. Iterable.forEach(Forbruger <? Super T> handling)

Navnet taler for sig selv. Det itererer over samlingen, der sendes som et argument, og udfører handlingen lambda-udtrykket for hvert af dets elementer.

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(prædikat<? super E> filter)

Igen, intet svært her. Metoden gentager samlingen og fjerner alle elementer, der matcher 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 + " "));
På en enkelt linje fjerner vi fra listen alle tal større end 5.

3. Map.forEach(BiConsumer <? super K, ? super V> handling)

Metoden forEachvirker ikke kun for klasser, der implementerer grænsefladen Collection, men også for 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-tast, BiFunction<? Super K,? Super V,? Udvider V> remappingFunction)

Ser lidt mere skræmmende ud, men faktisk simpel, ligesom alle de foregående. Denne metode sætter keyværdien lig med resultatet af udførelsen mappingFunction. For eksempel:

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
Forfatteren til "Thinking in Java" er bestemt sej! :)

5. Map.computeIfAbsent(K-tast, Funktion <? super K, ? udvider V> mappingFunction)

Denne metode tilføjer et nyt element til Map, men kun hvis det ikke allerede har et element med denne nøgle. Den tildelte værdi vil være resultatet af udførelse af mappingFunction. Hvis et element med nøglen allerede findes, vil det ikke blive overskrevet. Det forbliver simpelthen som det er. Lad os vende tilbage til vores bøger og prøve en ny metode:

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));
Her er vores mappingFunction:

public static String getHarryPotterAuthor() {
        return "Joanne Rowling";
    }
Og her er den nye bog:

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-tast, BiFunction<? super K, ? super V, ? udvider V> remappingFunction)

Her har vi samme princip som Map.compute(), men beregningerne udføres kun, hvis en vare med keyallerede eksisterer.

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));
Det første kald til funktionen gjorde ingen ændringer, fordi der ikke er nogen bog med titlen "Eugene Onegin" i vores Map. Men i det andet opkald ændrede programmet forfatteren til bogen "The Brothers Karamazov" til Alexander Pushkin. Produktion:

_________________
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(Objektnøgle, V defaultValue)

Denne metode returnerer den værdi, der svarer til key. Hvis nøglen ikke findes, returnerer den standardværdien.

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);
Dette er meget praktisk:

Unknown author

8. Map.merge(K-tast, V-værdi, BiFunction<? super V, ? super V, ? udvider V> remappingFunction)

Jeg gad ikke engang prøve at beregne, hvor mange linjer kode denne metode vil spare dig.
  1. Hvis den keyikke findes i din Map, eller hvis valuefor denne nøgle er null, tilføjer metoden det beståede key-valuepar til Map.
  2. Hvis keyder findes og dens value != null, så ændrer metoden sin værdi til resultatet af udførelsen remappingFunction.
  3. Hvis remappingFunctionreturnerer null, så keyfjernes fra samlingen.

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));
Produktion:

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
*undskyld, Bruce*

9. Map.putIfAbsent(K-tast, V-værdi)

Tidligere, for at tilføje et par til en Map, hvis det ikke allerede var der, skulle du gøre følgende:

Map <String, String> map = new HashMap<>();
if (map.get("Lord of the Rings") == null)
    map.put("Lord of the Rings", "John Tolkien");
Nu er alt blevet meget nemmere:

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

10. Map.replace og Map.replaceAll()

Sidst men ikke mindst.
  1. Map.replace(K key, V newValue)erstatter keyværdien med newValue, hvis en sådan nøgle findes. Hvis ikke, sker der ikke noget.
  2. Map.replace(K key, V oldValue, V newValue)gør det samme, men kun hvis den aktuelle værdi for keyer lig med oldValue.
  3. Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)erstatter hver valuemed resultatet af funktion.
For eksempel:

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
Det virkede ikke! Den aktuelle værdi for nøglen "The Brothers Karamazov" er "Fyodor Dostoevsky", ikke "Bruce Eckel", så intet er ændret.

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
Vi ændrede let værdierne for hele Mapuden nogen komplicerede konstruktioner! PS Det er altid svært at vænne sig til det nye, men disse ændringer er virkelig gode. Under alle omstændigheder er nogle dele af min kode bestemt mindre som spaghetti end før :) Held og lykke med at lære!
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION