Como você sabe, nossos hábitos são uma segunda natureza. E uma vez que você se acostuma a escrever
for (int i = 0; i <......)
, nenhuma parte de você quer ter que reaprender essa construção (especialmente porque é bastante simples e compreensível). No entanto, os loops são frequentemente usados repetidamente para executar as mesmas operações básicas, e a repetição é algo que gostaríamos muito de nos livrar. Com o Java 8, a Oracle decidiu nos ajudar a fazer isso. Abaixo estão os 10 melhores métodos de coleta que economizarão muito tempo e código.
1. Iterable.forEach(Consumer <? Super T> action)
O nome fala por si. Ele itera sobre a coleção passada como um argumento e executa a expressão lambda de ação para cada um de seus elementos.
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(filtro Predicate<? super E>)
Novamente, nada difícil aqui. O método itera sobre a coleção e remove todos os elementos correspondentesfilter
.
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 + " "));
Em uma única linha, estamos removendo da lista todos os números maiores que 5.
3. Map.forEach(BiConsumer <? super K, ? super V> ação)
OforEach
método funciona não apenas para classes que implementam a Collection
interface, mas também para 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 (tecla K, BiFunction<? Super K,? Super V,? Estende V> remappingFunction)
Parece um pouco mais intimidador, mas na verdade simples, como todos os anteriores. Este método definekey
o valor de igual ao resultado da execução mappingFunction
. Por exemplo:
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
O autor de "Thinking in Java" é definitivamente legal! :)
5. Map.computeIfAbsent(tecla K, Function <? super K, ? extends V> mappingFunction)
Este método adicionará um novo elemento aoMap
, mas apenas se ele ainda não tiver um elemento com essa chave. O valor atribuído será o resultado da execução do arquivo mappingFunction
. Se já existir um elemento com a chave, ele não será substituído. Ele simplesmente permanecerá como está. Vamos voltar aos nossos livros e tentar um novo método:
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));
Aqui está o nosso mappingFunction
:
public static String getHarryPotterAuthor() {
return "Joanne Rowling";
}
E aqui está o novo livro:
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 key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
Aqui temos o mesmo princípio deMap.compute()
, mas os cálculos são realizados apenas se key
já existir um item com.
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 primeira chamada para a função não fez alterações, porque não há nenhum livro intitulado "Eugene Onegin" em nosso arquivo Map
. Mas na segunda chamada, o programa mudou o autor do livro "Os Irmãos Karamazov" para Alexander Pushkin. Saída:
_________________
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(Chave do objeto, V defaultValue)
Este método retorna o valor correspondente akey
. Se a chave não existir, ela retornará o valor padrão.
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);
Isso é muito conveniente:
Unknown author
8. Map.merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)
Eu nem me preocupei em tentar calcular quantas linhas de código esse método economizará.- Se
key
não existir em seuMap
, ou se forvalue
esta chave fornull
, o método adicionará okey-value
par passado aoMap
. - Se
key
existir e forvalue != null
, o método altera seu valor para o resultado da execuçãoremappingFunction
. - Se
remappingFunction
retornarnull
, entãokey
será removido da coleção.
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));
Saída:
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
*desculpa Bru*
9. Map.putIfAbsent(chave K, valor V)
Anteriormente, para adicionar um par a umMap
, caso ainda não existisse, era necessário fazer o seguinte:
Map <String, String> map = new HashMap<>();
if (map.get("Lord of the Rings") == null)
map.put("Lord of the Rings", "John Tolkien");
Agora tudo ficou muito mais fácil:
Map<String, String> map = new HashMap<>();
map.putIfAbsent("Lord of the Rings", "John Tolkien");
10. Map.replace e Map.replaceAll()
Por último, mas não menos importante.Map.replace(K key, V newValue)
substituikey
o valor de pornewValue
, se tal chave existir. Se não, nada acontece.Map.replace(K key, V oldValue, V newValue)
faz a mesma coisa, mas apenas se o valor atual forkey
igual aoldValue
.Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
substitui cada umvalue
pelo resultado da função.
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
Não funcionou! O valor atual para a chave "Os Irmãos Karamazov" é "Fyodor Dostoevsky", não "Bruce Eckel", então nada mudou.
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
Mudamos facilmente os valores para o todo Map
sem construções complicadas! PS Acostumar-se com o novo é sempre difícil, mas essas mudanças são muito boas. De qualquer forma, algumas partes do meu código são definitivamente menos parecidas com espaguete do que antes :) Boa sorte no aprendizado!
GO TO FULL VERSION