JavaRush /Blog Java /Random-ES /HashMap en Java: ¿qué tipo de mapa es?

HashMap en Java: ¿qué tipo de mapa es?

Publicado en el grupo Random-ES
¡Hola! Hoy hablaremos de otra estructura de datos: Mapa. Su nombre oficial en ruso es “matriz asociativa”, pero no se utiliza con frecuencia. Las opciones más comunes son "diccionario", "mapa" o (más a menudo) el anglicismo "mapa" :) Dentro de Map, los datos se almacenan en el formato "clave" - ​​"valor", es decir, en pares. Tanto las claves como los valores pueden ser cualquier objeto: números, cadenas u objetos de otras clases.

En qué se diferencia Map de otras estructuras de datos

Anteriormente, analizamos las estructuras de datos donde los elementos se almacenan por sí mismos. En un array, o ArrayList / LinkedList , almacenamos una determinada cantidad de elementos. Pero ¿y si nuestra tarea cambia un poco? Por ejemplo, imaginemos que nos enfrentamos a la tarea de crear una lista de 100 personas, donde se almacenará el nombre completo y el número de pasaporte de la persona. En principio no es tan difícil. Por ejemplo, puede colocar ambas en una línea y crear una lista de líneas como esta: "Anna Ivanovna Reshetnikova, 4211 717171". Pero esta solución tiene dos inconvenientes. Primero, es posible que necesitemos una función de búsqueda de pasaportes. Y con este formato para almacenar información, esto será problemático. Y en segundo lugar, nada nos impedirá crear dos personas diferentes con el mismo número de pasaporte. Y este es el inconveniente más grave de nuestra solución. Este tipo de situaciones deben excluirse por completo: no hay dos personas con el mismo número de pasaporte. Aquí Map y sus características declaradas vienen en nuestra ayuda (almacenando datos en un par en el formato "clave"-"valor"). Veamos la implementación de mapas más común: la clase Java HashMap .HashMap: ¿qué tipo de mapa es este?  - 1

Creando un HashMap en Java y trabajando con la clase

Esta implementación es muy sencilla de crear:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

}
Aquí hemos creado un diccionario en el que los elementos se almacenarán en el formato "cadena de números". El número será la clave y la cadena será el valor. También indicamos qué tipo de claves tendremos ( Integer) y qué tipo de valores ( String). ¿Por qué esto es tan? Primero, la clave en un HashMap es siempre única . Esto nos funcionará muy bien porque podemos usar el número de pasaporte como clave y evitar duplicados. Y la línea con el nombre completo actuará como valor (el nombre completo de diferentes personas se puede repetir fácilmente, no tiene nada de malo para nosotros).

Agregar un nuevo par a un HashMap

Esta tarea se ve así:
public class Main {

   public static void main(String[] args) {
       HashMap<Integer, String> passportsAndNames = new HashMap<>();


       passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");
       System.out.println(passportsAndNames);

   }

}
Para ello se utiliza el método put(). Además, HashMap tiene un método anulado toString()para que pueda imprimirse en la consola. El resultado se verá así: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov}

Características de las claves HashMap

Ahora comprobemos si las claves son realmente únicas. Intentemos agregar un nuevo elemento con una clave que ya está en el mapa:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");
   passportsAndNames.put(162348, "Viktor Mijailovich Stychkin");//repetir clave

   System.out.println(passportsAndNames);

}
Salida: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Viktor Mikhailovich Stychkin} El elemento anterior con la clave 162348, como puede ver, fue sobrescrito. “La Clave” fue llamada la clave por una razón. Se accede a los valores en un HashMap mediante clave (pero no al revés: la clave no se puede obtener por valor, porque los valores se pueden duplicar). Esto se ve claramente en los ejemplos de cómo obtener un elemento, así como también eliminar un elemento de un HashMap:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   String lidiaName = passportsAndNames.get(212133);
   System.out.println(lidiaName);


   passportsAndNames.remove(162348);
   System.out.println(passportsAndNames);

}
Para obtener un valor o eliminar un par del diccionario, debemos pasar exactamente la clave única correspondiente a este valor a los get()métodos . No hay índices numéricos, como en las matrices o listas, en HashMap : se accede al valor mediante una clave. Salida de consola: Lidiya Arkadyevna Bublikova {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump}remove()

Comprobando la presencia de una clave y un valor.

En las clases ArrayList y LinkedList , podríamos verificar si una lista contiene un elemento en particular. HashMap también le permite hacer esto, y para ambas partes del par: tiene métodos containsKey()(verifica la presencia de una clave) y containsValue()(verifica la presencia de un valor).
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");


   System.out.println(passportsAndNames.containsKey(11111));
   System.out.println(passportsAndNames.containsValue("Donald John Trump"));

}
Salida: falso verdadero

Obtener una lista de todas las claves y valores

Otra característica conveniente de HashMap es que puede obtener por separado una lista de todas las claves y todos los valores . Para ello se utilizan métodos keySet()y values():
public class Main {

   public static void main(String[] args) {

       HashMap<Integer, String> passportsAndNames = new HashMap<>();

       passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");

       Set<Integer> keys = passportsAndNames.keySet();
       System.out.println("Llaves: " + keys);

       ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
       System.out.println("Valores: " + values);

   }

}
Las claves se extraen en la colección Set. Su peculiaridad es que no puede contener elementos repetidos. Ahora lo principal que hay que recordar es que la lista de todas las claves se puede sacar del HashMap y colocarla en una colección separada. En el ejemplo, guardamos los valores en normal ArrayList. Salida de la consola: Claves: [212133, 8082771, 162348] Valores: [Lidiya Arkadyevna Bublikova, Donald John Trump, Ivan Mikhailovich Serebryakov] Los métodos size()hacen clear()exactamente lo mismo que en las estructuras anteriores que analizamos: el primero devuelve un número de elementos en el diccionario en el momento actual, el segundo elimina todos los elementos.
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   System.out.println(passportsAndNames.size());
   passportsAndNames.clear();
   System.out.println(passportsAndNames);

}
Salida: 3 {} Para comprobar si nuestro HashMap tiene al menos un elemento, podemos usar el método isEmpty():
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   if (!passportsAndNames.isEmpty()) {

       System.out.println(passportsAndNames);

   }

}
Salida: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov} Ahora saldremos a la consola solo después de la verificación preliminar :)

Combinando dos mapas en uno

Otro punto interesante es que se pueden combinar dos mapas en uno . Hay un método para esto putAll(). Lo llamamos en el primer HashMap , pasamos el segundo como argumento y los elementos del segundo se agregarán al primero:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();
   HashMap<Integer, String> passportsAndNames2 = new HashMap<>();

   passportsAndNames.put(212133, "Lidia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Iván Mijailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   passportsAndNames2.put(917352, "Alexei Andreevich Ermakov");
   passportsAndNames2.put(925648, "Maxim Olegovich Arkharov");


   passportsAndNames.putAll(passportsAndNames2);
   System.out.println(passportsAndNames);

}
Salida: {917352=Alexey Andreevich Ermakov, 212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 925648=Maxim Olegovich Arkharov, 162348=Ivan Mikhailovich Serebryakov} Todos los elementos de PassportsAndNames2 se copiaron en PassportsAndNames . Ahora veamos un ejemplo más complicado. Es decir, iterar sobre HashMap en un bucle.
for (Map.Entry entry: passportsAndNames.entrySet()) {

   System.out.println(entry);

}
Una interfaz Map.Entrysimplemente significa un par clave-valor dentro de un diccionario. El método entrySet()devuelve una lista de todos los pares en nuestro HashMap (dado que nuestro mapa consta solo de esos pares de Entrada, iteramos sobre pares, y no sobre claves o valores por separado). Conclusión: 212133=Lidiya Arkadyevna Bublikova 8082771=Donald John Trump 162348=Ivan Mikhailovich Serebryakov Guarde este artículo para el futuro: https://habr.com/ru/post/128017/ Ahora es demasiado pronto para leerlo, pero en el futuro Cuando empiece a utilizar HashMap, le ayudará a comprender cómo funciona esta estructura de datos desde dentro. Además, no olvide consultar la documentación oficial de Oracle en HashMap.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION