![Slutt å skrive looper! Topp 10 beste fremgangsmåter for å jobbe med samlinger i Java 8 - 1]()
Som du vet, er vanene våre en annen natur. Og når du først har blitt vant til å skrive
for (int i = 0; i <......)
, vil ingen del av deg måtte lære denne konstruksjonen på nytt (spesielt siden den er ganske enkel og forståelig). Men løkker brukes ofte gjentatte ganger for å utføre de samme grunnleggende operasjonene, og repetisjon er noe vi veldig gjerne vil bli kvitt. Med Java 8 har Oracle bestemt seg for å hjelpe oss med dette. Nedenfor er de 10 beste innsamlingsmetodene som vil spare deg for massevis av tid og kode.
1. Iterable.forEach(Forbruker <? Super T> handling)
Navnet taler for seg selv. Den itererer over samlingen som sendes som et argument, og utfører handlingen lambda-uttrykk for hvert av elementene.
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)
Igjen, ikke noe vanskelig her. Metoden itererer over samlingen og fjerner alle elementer som samsvarer
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 tall større enn 5.
3. Map.forEach(BiConsumer <? super K, ? super V> handling)
Metoden
forEach
fungerer ikke bare for klasser som implementerer grensesnittet
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,? Utvider V> remappingFunction)
Ser litt mer skremmende ut, men faktisk enkelt, som alle de forrige. Denne metoden setter
key
verdien lik resultatet av utførelse
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 av "Thinking in Java" er definitivt kul! :)
5. Map.computeIfAbsent(K-tast, funksjon <? super K, ? utvider V> mappingFunction)
Denne metoden vil legge til et nytt element til
Map
, men bare hvis den ikke allerede har et element med den nøkkelen. Den tildelte verdien vil være resultatet av å utføre
mappingFunction
. Hvis et element med nøkkelen allerede eksisterer, vil det ikke bli overskrevet. Det vil rett og slett forbli som det er. La oss gå tilbake til bøkene våre 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 vår
mappingFunction
:
public static String getHarryPotterAuthor() {
return "Joanne Rowling";
}
Og her er den nye 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-tast, BiFunction<? super K, ? super V, ? utvider V> remappingFunction)
Her har vi samme prinsipp som
Map.compute()
, men beregningene utføres kun hvis en vare med
key
allerede 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 kallet til funksjonen gjorde ingen endringer, fordi det ikke er noen bok med tittelen "Eugene Onegin" i vår
Map
. Men i den andre samtalen endret programmet forfatteren av boken "The Brothers Karamazov" til Alexander Pushkin. Produksjon:
_________________
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økkel, V defaultValue)
Denne metoden returnerer verdien som tilsvarer
key
. Hvis nøkkelen ikke eksisterer, returnerer den standardverdien.
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 veldig praktisk:
Unknown author
8. Map.merge(K-tast, V-verdi, BiFunction<? super V, ? super V, ? utvider V> remappingFunction)
Jeg gadd ikke engang å prøve å beregne hvor mange linjer med kode denne metoden vil spare deg for.
- Hvis
key
ikke eksisterer i din Map
, eller hvis value
for denne nøkkelen er null
, så legger metoden det beståtte key-value
paret til Map
.
- Hvis
key
det eksisterer og dens value != null
, endrer metoden sin verdi til resultatet av utførelse remappingFunction
.
- Hvis
remappingFunction
returnerer null
, key
fjernes den 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));
Produksjon:
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
*beklager, Bruce*
9. Map.putIfAbsent(K-tast, V-verdi)
Tidligere, for å legge til et par til en
Map
, hvis det ikke allerede var der, måtte du gjø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");
Nå har alt blitt mye enklere:
Map<String, String> map = new HashMap<>();
map.putIfAbsent("Lord of the Rings", "John Tolkien");
10. Map.replace og Map.replaceAll()
Sist men ikke minst.
Map.replace(K key, V newValue)
erstatter key
verdien med newValue
, hvis en slik nøkkel eksisterer. Hvis ikke skjer det ingenting.
Map.replace(K key, V oldValue, V newValue)
gjør det samme, men bare hvis gjeldende verdi for key
er lik oldValue
.
Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
erstatter hver value
med resultatet av funksjon.
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 gikk ikke! Den nåværende verdien for nøkkelen "The Brothers Karamazov" er "Fyodor Dostoevsky", ikke "Bruce Eckel", så ingenting har endret seg.
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 endret enkelt verdiene for hele
Map
uten noen kompliserte konstruksjoner! PS Å bli vant til det nye er alltid vanskelig, men disse endringene er veldig bra. I alle fall er noen deler av koden min definitivt mindre som spaghetti enn før :) Lykke til med læringen!
GO TO FULL VERSION