Sluta skriva loopar!  Topp 10 bästa metoder för att arbeta med samlingar i Java 8 - 1 Som ni vet är våra vanor en andra natur. Och när du väl har vant dig vid att skriva for (int i = 0; i <......), vill ingen del av dig behöva lära dig om denna konstruktion (särskilt eftersom det är ganska enkelt och begripligt). Men slingor används ofta upprepade gånger för att utföra samma grundläggande operationer, och upprepning är något vi väldigt gärna vill bli av med. Med Java 8 har Oracle bestämt sig för att hjälpa oss att göra detta. Nedan är de 10 bästa insamlingsmetoderna som kommer att spara massor av tid och kod.

1. Iterable.forEach(Consumer <? Super T> action)

Namnet talar för sig självt. Den itererar över samlingen som skickas som ett argument och exekverar åtgärden lambda-uttryck för vart och ett av dess element.

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(Predikat<? super E> filter)

Återigen, inget svårt här. Metoden itererar över samlingen och tar bort alla element som matchar 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 enda rad tar vi bort alla siffror större än 5 från listan.

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

Metoden forEachfungerar inte bara för klasser som implementerar gränssnittet, Collectionutan även för 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-tangent, BiFunction<? Super K,? Super V,? Extends V> remappingFunction)

Ser lite mer skrämmande ut, men i själva verket enkel, som alla tidigare. Denna metod sätter keyvärdet lika med resultatet av exekvering mappingFunction. Till exempel:

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
Författaren till "Thinking in Java" är definitivt cool! :)

5. Map.computeIfAbsent(K-tangent, Funktion <? super K, ? utökar V> mappingFunction)

Denna metod kommer att lägga till ett nytt element till Map, men bara om det inte redan har ett element med den nyckeln. Det tilldelade värdet blir resultatet av exekvering av mappingFunction. Om ett element med nyckeln redan finns, kommer det inte att skrivas över. Det kommer helt enkelt att förbli som det är. Låt oss gå tillbaka till våra böcker och prova en ny metod:

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));
Här är vår mappingFunction:

public static String getHarryPotterAuthor() {
        return "Joanne Rowling";
    }
Och här är den nya boken:

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-nyckel, BiFunction<? super K, ? super V, ? utökar V> remappingFunction)

Här har vi samma princip som Map.compute(), men beräkningarna utförs endast om en artikel med keyredan finns.

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örsta anropet till funktionen gjorde inga ändringar, eftersom det inte finns någon bok med titeln "Eugene Onegin" i vår Map. Men i det andra samtalet ändrade programmet författaren till boken "The Brothers Karamazov" till 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(Objektnyckel, V defaultValue)

Denna metod returnerar värdet som motsvarar key. Om nyckeln inte finns returnerar den standardvärdet.

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);
Det här är väldigt bekvämt:

Unknown author

8. Map.merge(K-nyckel, V-värde, BiFunction<? super V, ? super V, ? utökar V> remappingFunction)

Jag brydde mig inte ens om att försöka beräkna hur många rader kod den här metoden kommer att spara dig.
  1. Om det keyinte finns i din Map, eller om valueför denna nyckel är null, så lägger metoden till det passerade key-valueparet till Map.
  2. Om keydet finns och dess value != null, ändrar metoden sitt värde till resultatet av exekvering remappingFunction.
  3. Om remappingFunctionreturer nulltas keybort från 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
*förlåt Bruce*

9. Map.putIfAbsent(K-nyckel, V-värde)

Tidigare, för att lägga till ett par till en Map, om det inte redan fanns där, var du tvungen att göra följande:

Map <String, String> map = new HashMap<>();
if (map.get("Lord of the Rings") == null)
    map.put("Lord of the Rings", "John Tolkien");
Nu har allt blivit mycket lättare:

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

10. Map.replace och Map.replaceAll()

Sist men inte minst.
  1. Map.replace(K key, V newValue)ersätter keyvärdet med newValue, om en sådan nyckel finns. Om inte händer ingenting.
  2. Map.replace(K key, V oldValue, V newValue)gör samma sak, men bara om det aktuella värdet för keyär lika med oldValue.
  3. Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)ersätter var och en valuemed resultatet av funktion.
Till exempel:

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 fungerade inte! Det aktuella värdet för nyckeln "The Brothers Karamazov" är "Fyodor Dostoevsky", inte "Bruce Eckel", så ingenting har förändrats.

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 ändrade enkelt värdena för hela Maputan några komplicerade konstruktioner! PS Att vänja sig vid det nya är alltid svårt, men dessa förändringar är riktigt bra. I vilket fall som helst, vissa delar av min kod är definitivt mindre som spagetti än tidigare :) Lycka till med lärandet!