CodeGym/Blog Java/Random-ES/¡Deja de escribir bucles! Las 10 mejores prácticas para t...
John Squirrels
Nivel 41
San Francisco

¡Deja de escribir bucles! Las 10 mejores prácticas para trabajar con colecciones en Java 8

Publicado en el grupo Random-ES
¡Deja de escribir bucles!  Las 10 mejores prácticas para trabajar con colecciones en Java 8 - 1 Como saben, nuestros hábitos son una segunda naturaleza. Y una vez que te acostumbras a escribir for (int i = 0; i <......), ninguna parte de ti quiere tener que volver a aprender esta construcción (especialmente porque es bastante simple y comprensible). Sin embargo, los bucles a menudo se usan repetidamente para realizar las mismas operaciones básicas, y la repetición es algo de lo que nos gustaría deshacernos. Con Java 8, Oracle ha decidido ayudarnos a hacer esto. A continuación se encuentran los 10 mejores métodos de recopilación que le ahorrarán una tonelada de tiempo y código.

1. Iterable.forEach (Consumidor <? Super T> acción)

El nombre habla por sí mismo. Itera sobre la colección pasada como argumento y ejecuta la expresión action lambda para cada uno de sus 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(predicado<? filtro super E>)

Una vez más, nada difícil aquí. El método itera sobre la colección y elimina cualquier elemento que coincida 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 + " "));
En una sola línea, estamos eliminando de la lista todos los números mayores de 5.

3. Map.forEach(BiConsumer <? super K, ? super V> acción)

El forEachmétodo funciona no solo para clases que implementan la Collectioninterfaz, sino también 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,? Extends V> función de reasignación)

Parece un poco más intimidante, pero en realidad simple, como todos los anteriores. Este método establece keyel valor de igual al resultado de la ejecución mappingFunction. Por ejemplo:
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
¡El autor de "Pensar en Java" es definitivamente genial! :)

5. Map.computeIfAbsent (tecla K, función <? super K, ? extiende V> función de mapeo)

Este método agregará un nuevo elemento al Map, pero solo si aún no tiene un elemento con esa clave. El valor asignado será el resultado de ejecutar el mappingFunction. Si ya existe un elemento con la clave, no se sobrescribirá. Simplemente permanecerá como está. Volvamos a nuestros libros y probemos un nuevo 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));
Aquí está nuestro mappingFunction:
public static String getHarryPotterAuthor() {
        return "Joanne Rowling";
    }
Y aquí está el nuevo libro:
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(tecla K, BiFunction<? super K, ? super V, ? extiende V> función de reasignación)

Aquí tenemos el mismo principio que Map.compute(), pero los cálculos se realizan solo si ya existe un elemento key.
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));
La primera llamada a la función no hizo cambios, porque no hay ningún libro titulado "Eugene Onegin" en nuestro archivo Map. Pero en la segunda convocatoria, el programa cambió al autor del libro "Los hermanos Karamazov" a Alexander Pushkin. Producción:
_________________
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 (clave de objeto, valor predeterminado de V)

Este método devuelve el valor correspondiente a key. Si la clave no existe, devuelve el valor predeterminado.
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);
Esto es muy conveniente:
Unknown author

8. Map.merge (tecla K, valor V, BiFunction<? super V, ? super V, ? extiende V> función de reasignación)

Ni siquiera me molesté en intentar calcular cuántas líneas de código te ahorrará este método.
  1. Si keyno existe en su Map, o si valuepara esta clave es null, entonces el método agrega el key-valuepar pasado al Map.
  2. Si keyexiste y es value != null, entonces el método cambia su valor al resultado de la ejecución remappingFunction.
  3. Si remappingFunctiondevuelve null, keyse elimina de la colección.
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));
Producción:
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
*lo siento Bruce*

9. Map.putIfAbsent (clave K, valor V)

Anteriormente, para agregar un par a un Map, si aún no estaba allí, tenía que hacer lo siguiente:
Map <String, String> map = new HashMap<>();
if (map.get("Lord of the Rings") == null)
    map.put("Lord of the Rings", "John Tolkien");
Ahora todo se ha vuelto mucho más fácil:
Map<String, String> map = new HashMap<>();
map.putIfAbsent("Lord of the Rings", "John Tolkien");

10. Map.replace y Map.replaceAll()

Por último, pero no menos importante.
  1. Map.replace(K key, V newValue)reemplaza keyel valor de con newValue, si existe tal clave. Si no, no pasa nada.
  2. Map.replace(K key, V oldValue, V newValue)hace lo mismo, pero solo si el valor actual de keyes igual a oldValue.
  3. Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)reemplaza cada uno valuecon el resultado de la función.
Por ejemplo:
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
¡No funcionó! El valor actual de la clave "Los hermanos Karamazov" es "Fiodor Dostoievski", no "Bruce Eckel", por lo que nada ha cambiado.
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
¡Cambiamos fácilmente los valores para el conjunto Mapsin construcciones complicadas! PD: Siempre es difícil acostumbrarse a lo nuevo, pero estos cambios son realmente buenos. En cualquier caso, algunas partes de mi código son definitivamente menos espaguetis que antes :) ¡Buena suerte en el aprendizaje!
Comentarios
  • Populares
  • Nuevas
  • Antiguas
Debes iniciar sesión para dejar un comentario
Esta página aún no tiene comentarios