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 matcharfilter
.
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)
MetodenforEach
fungerar inte bara för klasser som implementerar gränssnittet, Collection
utan ä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ätterkey
vä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 tillMap
, 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 somMap.compute()
, men beräkningarna utförs endast om en artikel med key
redan 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 motsvararkey
. 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.- Om det
key
inte finns i dinMap
, eller omvalue
för denna nyckel ärnull
, så lägger metoden till det passeradekey-value
paret tillMap
. - Om
key
det finns och dessvalue != null
, ändrar metoden sitt värde till resultatet av exekveringremappingFunction
. - Om
remappingFunction
returernull
taskey
bort 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 enMap
, 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.Map.replace(K key, V newValue)
ersätterkey
värdet mednewValue
, om en sådan nyckel finns. Om inte händer ingenting.Map.replace(K key, V oldValue, V newValue)
gör samma sak, men bara om det aktuella värdet förkey
är lika medoldValue
.Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
ersätter var och envalue
med resultatet av funktion.
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 Map
utan 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!
GO TO FULL VERSION