CodeGym /Blogue Java /Random-PT /Pare de escrever loops! As 10 melhores práticas para trab...
John Squirrels
Nível 41
San Francisco

Pare de escrever loops! As 10 melhores práticas para trabalhar com coleções no Java 8

Publicado no grupo Random-PT
Pare de escrever loops!  As 10 melhores práticas para trabalhar com coleções em Java 8 - 1 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 correspondentes 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 + " "));
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)

O forEachmétodo funciona não apenas para classes que implementam a Collectioninterface, 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 define keyo 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 ao Map, 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 de Map.compute(), mas os cálculos são realizados apenas se keyjá 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 a key. 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á.
  1. Se keynão existir em seu Map, ou se for valueesta chave for null, o método adicionará o key-valuepar passado ao Map.
  2. Se keyexistir e for value != null, o método altera seu valor para o resultado da execução remappingFunction.
  3. Se remappingFunctionretornar null, então keyserá 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 um Map, 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.
  1. Map.replace(K key, V newValue)substitui keyo valor de por newValue, se tal chave existir. Se não, nada acontece.
  2. Map.replace(K key, V oldValue, V newValue)faz a mesma coisa, mas apenas se o valor atual for keyigual a oldValue.
  3. Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)substitui cada um valuepelo resultado da função.
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.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 Mapsem 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!
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION