Métodos de fábrica de conveniencia de Java para colecciones

El JDK 9 ha agregado métodos de fábrica estáticos como of() en las interfaces de colección básicas, para crear objetos de colección no modificables. Estos son los mismos que la colección no modificable (inmutable) que creamos en JDK 6, 7, 8. Le permite crear una lista, un conjunto y un mapa de valores en una sola línea. Java 9 no trae tantos cambios dramáticos a nuestra forma de codificar como lo hizo su predecesor, pero seguramente tendremos algunas funciones sofisticadas.

 Las formas mencionadas a continuación conducen a la creación de objetos innecesarios. Para superar este problema, Java 9 ha introducido métodos de fábrica estáticos para crear una lista, un conjunto y un mapa inmutables que se analizarán más adelante. antes de eso, revisemos la creación de una Colección no modificable antes de JDK 9 (JDK 7, 8).

Lista en JDK 8

List<String> listOfString = new ArrayList<>();
listOfString.add("Geeks");
listOfString.add("Java");
listOfString.add("Kotlin");
listOfString.add("Groovy");
listOfString.add("Scala");
listOfString = Collections.unmodifiableList(listOfString);

 Forma 1: usar la inicialización de llaves dobles

List<String> listOfString = Collections.unmodifiableList(new ArrayList<>() {

    {

        add(“Geeks”);

        agregar(“Java”);

        agregar(“Kotlin”);

        add(“Maravilloso”);

        agregar(“Escala”);

    }

});

Forma 2: usar la API de Arrays para convertir una array en una ArrayList

List<String> listOfString = Collections.unmodifiableList(Arrays.asList(“Geeks”,”Java”,”Kotlin”,”Groovy”, “Scala”));

Forma 3: usar la API de transmisión 

List<String> listOfString = Collections.unmodifiableList(Stream.of(“Bruce”,”Steve”,”Adrian”, “Dave”, “Janick”,”Nicko”).collect(toList()));

¿Por qué Java 9?

Ahora veamos los beneficios antes de por qué usar los métodos de fábrica estáticos de Java 9 antes de saltar sobre ellos.

  • Permite crear una lista, conjunto y mapa de valores en una sola línea.
  • La creación de objetos inmutables usando métodos estáticos de fábrica nos impide insertar nulos o duplicados (en Conjuntos o Mapas).
  • Estamos a salvo de obtener NullPointerExceptions al atravesar los elementos de la colección.

Ahora analicemos la creación de una colección no modificable en JDK. Aquí la lista, el conjunto y el mapa se analizan a continuación.

1. Lista en Java 9 

List<String> listOfString = List.of("Geeks", "Java", "Kotlin", "Groovy", "Scala");

Solo una línea de código es suficiente para crear una lista no modificable, por lo que no se involucra la creación de objetos innecesarios.

  • List.of() le permite crear una lista inmutable vacía.
  • Cualquier modificación causará UnsupportedOperationException.
  • Varias versiones sobrecargadas de List.of() están disponibles desde la perspectiva del rendimiento.

Una lista inmutable tiene una clase base abstracta AbstractImmutableList<E> y cuatro implementaciones:

  • Lista0<E>
  • Lista1<E>
  • Lista2<E>
  • ListaN<E>

Cada uno de estos tipos corresponde al número de elementos que se utilizan para su creación. En la interfaz java.util.List, tenemos 12 métodos de fábrica estáticos que utilizan las implementaciones anteriores para crear objetos inmutables:

// creates empty immutable list
static <E> List<E> of()

// creates one-element immutable list
static <E> List<E> of(E e1)

// creates two-element immutable list
static <E> List<E> of(E e1, E e2)

// creates ten-element immutable list
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

// creates N-element immutable list
static <E> List<E> of(E... elements)

También escabullirse de los métodos que arrojan UnsupportedOperationException , a saber, de la siguiente manera

  • add(E e), addAll(Colección<? extiende E> c), addAll(int index, Collection<? extiende E> c)
  • remove(Object o), removeAll(Colección<?> c), removeIf(Predicate<? super E> filter)
  • replaceAll (operador UnaryOperator<E>)
  • retenerTodo(Colección<?> c)
  • sort(Comparador<? super E> c)
  • clear()

Insertar valores Null causará NullPointerException  como se muestra a continuación

List<String> listOfString = List.of("Geeks","Java","Kotlin", "Scala", "Groovy", null);
// throws NullPointerException

Por lo tanto, la creación válida de una lista inmutable es la siguiente: 

List<String> listOfString = List.of("Geeks","Java","Kotlin", "Scala", "Groovy","Pearl");

2. Establecer en Java 9 

  • Set.of() le permite crear un conjunto inmutable vacío.
  • Cualquier modificación causará UnsupportedOperationException.
  • Varias versiones sobrecargadas de Set.of() están disponibles desde el punto de vista del rendimiento.

Ilustración:

Un conjunto inmutable se implementa de manera similar a como vimos con la interfaz List. Tiene una clase base abstracta AbstractImmutableSet<E> y cuatro implementaciones:

  • Establecer0<E>
  • Conjunto1<E>
  • Conjunto2<E>
  • EstablecerN<E>

Eso nuevamente corresponde a la cantidad de elementos que se utilizan en su creación. En la  interfaz java.util.Set , tenemos 12 métodos estáticos de fábrica: 

// creates empty immutable set
static <E> Set<E> of()

// creates one-element immutable set
static <E> Set<E> of(E e1)

// creates two-element immutable set
static <E> Set<E> of(E e1, E e2)

// creates ten-element immutable set
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

// creates N-element immutable set
static <E> Set<E> of(E... elements)

Los métodos que lanzan UnsupportedOperationException son los siguientes:

  1. add(E e), addAll(Colección<? extiende E> c)
  2. remove(Object o), removeAll(Colección<?> c), removeIf(Predicate<? super E> filter)
  3. retenerTodo(Colección<?> c)
  4. clear()

Ilustración:

Al igual que con las listas inmutables, no podemos crear instancias de un Conjunto con un valor nulo, ya que arroja NullPointerException donde agregar duplicados conducirá a IllegalArgumentException como se muestra a continuación:

Set<String> setOfString = Set.of("Geeks", "Java", "Kotlin", "Scala", "Groovy", null);
// throws NullPointerException

Set<String> setOfString = Set.of("Geeks", "Java", "Kotlin", "Java");
// throws IllegalArgumentException

Por lo tanto, la creación válida de un conjunto inmutable es la siguiente:

Set<String> setOfString = Set.of("Geeks", "Java", "Kotlin", "Scala", "Groovy", "Pearl");

3. Mapa en Java 9 

  • Map.of() y Map.ofEntries() le permiten crear un mapa inmutable.
  • Cualquier modificación causará UnsupportedOperationException.
  • Map.of() está sobrecargado para crear un mapa de 10 pares clave-valor como máximo.
  • Map.ofEntries() se utilizará para crear un mapa de más de 10 pares clave-valor.

Un mapa inmutable tiene una clase base abstracta, AbstractImmutableMap<K, V>, con tres implementaciones:

  • Mapa0<K, V>
  • Mapa1<K, V>
  • MapaN<K, V>

Nuevamente tenemos el siguiente conjunto de métodos de fábrica dentro de la interfaz java.util.Map . 

// creates an empty map
static <K, V> Map<K, V> of()

// creates one-element map
static <K, V> Map<K, V> of(K k1, V v1)

// creates two-element map
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2)

// creates ten-element map
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4,
                           K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, 
                           K k9, V v9, K k10, V v10)

// creates N-element map
static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries)

Nuevamente, los métodos que lanzan una UnsupportedOperationException son los siguientes:

  • clear()
  • calcular (tecla K, BiFunction<? super K,? super V,? extiende V> rf)
  • computar si está ausente (tecla K, función <? super K,? extiende V> mf)
  • ComputeIfPresent(tecla K, BiFunction<? super K,? super V,? extiende V> rf)
  • fusionar (tecla K, valor V, BiFunction<? super V,? super V,? extiende V> rf)
  • put(clave K, valor V), putAll(mapa<? extiende K,? extiende V> m), putIfAbsent(clave K, valor V)
  • eliminar (clave de objeto), eliminar (clave de objeto, valor de objeto)
  • reemplazar (tecla K, valor V), reemplazar (tecla K, V valor anterior, V valor nuevo), reemplazar todo (BiFunción <? super K,? super V,? extiende V> f)

Ilustración:

Insertar una clave o valor nulo provocará una excepción NullPointerException: 

Map<String, Integer> weightInKg = Map.of(null, 59, "John", 61);
// throws NullPointerExcepton because of null key
Map<String, Integer> weightInKg = Map.of("Ron", null, "John", 61);
// throws NullPointerExcepton because of null value
Map<String, Integer> weightInKg = Map.ofEntries(Map.entry("Ron", 59), null);
// throws NullPointerExcepton because of null entry

Agregar un elemento clave duplicado generará IllegalArgumentException:

Map<String, Integer> weightInKg = Map.of("Ron", 59, "Ron", 59);
Map<String, Long> weightInKg = Map.ofEntries(Map.entry("Ron", 59), Map.entry("Ron", 59));

La creación válida de un mapa inmutable es la siguiente:

Map<String, Long> weightInKg = Map.of("Ron", 59, "John", 61, "Ed", 60, "Nick", 60, "Jack", 60L, "Ben", 65);
Map<String, Long> age = Map.ofEntries(Map.entry("Ron", 59),
                                      Map.entry("John", 61),
                                      Map.entry("Ed", 60),
                                      Map.entry("Nick", 60),
                                      Map.entry("Jack", 60),
                                      Map.entry("Ben", 65));

Publicación traducida automáticamente

Artículo escrito por vanshitatwr620 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *