JavaRush /Blog Java /Random-ES /Respuestas a las preguntas más populares sobre la interfa...

Respuestas a las preguntas más populares sobre la interfaz del Mapa

Publicado en el grupo Random-ES
¡Hola! Hoy daremos respuesta a las preguntas más habituales sobre Map, pero primero recordemos qué es. Respuestas a las preguntas más populares sobre la interfaz del Mapa - 1Un mapa es una estructura de datos que contiene un conjunto de pares clave-valor. Su estructura de datos se asemeja a un diccionario, por eso a menudo se le llama así. Al mismo tiempo, Map es una interfaz y en el jdk estándar contiene las principales implementaciones: Hashmap, LinkedHashMap, Hashtable, TreeMap. La implementación más utilizada es Hashmap, por lo que la usaremos en nuestros ejemplos. Así es como se ve la creación y el llenado estándar de un mapa:
Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
Y así es como obtener valores por clave:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
Si todo lo anterior está claro, ¡continuemos con nuestras respuestas a preguntas populares!

0. Cómo iterar a través de todos los valores del mapa

Iterar sobre valores es la operación más común que se realiza con mapas. Todos los pares clave-valor se almacenan en la interfaz interna Map.Entry y, para obtenerlos, debe llamar al archivo entrySet(). Devuelve un conjunto de pares que se pueden recorrer en bucle:
for(Map.Entry<Integer, String> entry: map.entrySet()) {
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
   Map.Entry<Integer, String> entry =  itr.next();
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

1. Cómo convertir un mapa en una lista

La interfaz Map tiene 3 métodos que devuelven una lista de elementos:
  • keySet() - devuelve un conjunto de claves;
  • valores() - devuelve una colección de valores;
  • EntrySet(): devuelve un conjunto de conjuntos clave-valor.
Si observa los constructores de la clase ArrayList, notará que hay un constructor con un argumento de tipo Colección. Dado que Set es descendiente de Collection, los resultados de todos los métodos anteriores se pueden pasar al constructor de la clase ArrayList. Entonces crearemos nuevas listas y las llenaremos con valores de Map:
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());

2. Cómo ordenar las claves del mapa

Ordenar mapas también es una operación bastante común en programación. Puedes hacer esto de varias maneras:
  1. Coloque Map.Entry en una lista y ordénelo usando Comparator .

    En el comparador compararemos sólo las claves de pares:

    List> list = new ArrayList(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
       @Override
       public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
           return o1.getKey() - o2.getKey();
       }
    });
    

    Si comprende las lambdas, esta entrada se puede acortar significativamente:

    Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
  2. Utilice SortedMap, o más precisamente, su implementación TreeMap, que toma un Comparador en su constructor. Este comparador se aplicará a las claves del mapa, por lo que las claves deben ser clases que implementen la interfaz Comparable:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() {
       @Override
       public int compare(Integer o1, Integer o2) {
           return o1 - o2;
       }
    });

    Y, por supuesto, todo se puede reescribir usando lambdas:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));

    A diferencia del primer método, al usar SortedMap, siempre almacenaremos los datos en forma ordenada.

3. Cómo ordenar los valores del mapa

Aquí debería utilizar un enfoque similar al primero para las claves: obtener una lista de valores y ordenarlos en la lista:
List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
   @Override
   public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
       return o1.getValue().compareTo(o2.getValue());
   }
});
Y la lambda para esto se ve así:
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));

4. ¿Cuál es la diferencia entre HashMap, TreeMap y Hashtable?

Como se mencionó anteriormente, existen 3 implementaciones principales de la interfaz Map. Cada uno de ellos tiene sus propias características:
  1. Orden de elementos. HashMapy Hashtableno garantizamos que los artículos se almacenen en el orden en que fueron agregados. Además, no garantizan que el orden de los elementos no cambie con el tiempo. A su vez, TreeMapgarantiza el almacenamiento de los elementos en el orden en que fueron agregados o de acuerdo con un comparador determinado.

  2. Valores válidos. HashMapte permite tener una clave y un valor nulo, HashTableno. TreeMap sólo puede utilizar valores nulos si el comparador lo permite. Sin utilizar un comparador (almacenando pares en el orden en que se agregaron), no se permite nulo.

  3. Sincronización. Solo HashTablesincronizados, el resto no. Si diferentes subprocesos no accederán al mapa, se recomienda utilizar HashMap en lugar de HashTable.

Y una comparación general de implementaciones:
HashMap Tabla de picadillo ÁrbolMapa
Orden de elementos No No
nulo como valor No No precisamente
Seguridad del hilo No No
Complejidad algorítmica de la búsqueda de elementos. O(1) O(1) O(log n)
Estructura de datos bajo el capó tabla de picadillo tabla de picadillo árbol rojo-negro

5. Cómo crear un mapa bidireccional

A veces se hace necesario utilizar una estructura de datos en la que tanto las claves como los valores serán únicos, es decir, el mapa contendrá pares clave-clave. Esta estructura de datos le permite crear una “vista/búsqueda invertida” en el mapa. Es decir, podemos encontrar una clave por su valor. Esta estructura de datos se denomina mapa bidireccional y, lamentablemente, no es compatible con el JDK. Pero, afortunadamente, su implementación se puede encontrar en las colecciones comunes de Apache o en las bibliotecas de Guava. Allí se llama BidiMap y BiMap, respectivamente. Estas implementaciones imponen restricciones a la unicidad de claves y valores. Esto crea una relación uno a uno.

6. Cómo crear un mapa vacío

Hay dos formas de crear un mapa vacío:
  1. Inicialización normal de objetos:

    Map<Integer, String> emptyMap = new HashMap<>();
  2. Creando un mapa vacío inmutable:

    Map<Integer, String> emptyMap =  Collections.emptyMap();
Cuando intentamos agregar datos a dicho mapa, recibiremos: UnsupportedOperationExceptionexcepción. En este artículo, analizamos las preguntas más comunes que puede tener al utilizar la interfaz del Mapa.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION