Java Maps
Introducción
Los Maps en Java son estructuras de datos que representan una colección de pares clave-valor. Implementan la interfaz java.util.Map
y son extremadamente útiles para almacenar y recuperar datos de manera eficiente.
Creación de un Map
Existen varias implementaciones de Map en Java. Las más comunes son HashMap
y TreeMap
.
1Map<String, Integer> mapaNombresEdades = new HashMap<>();2Map<Integer, String> mapaCodigosProductos = new TreeMap<>();
Es una buena práctica utilizar genéricos para especificar los tipos de las claves y valores. Esto es, definir el tipo de dato que se almacenará en el Map
.
Inserción de elementos
Para agregar elementos a un Map
, utilizamos el método put()
:
1Map<String, List<String>> mapaEstudiantesCursos = new HashMap<>();2
3List<String> cursosAna = new ArrayList<>();4cursosAna.add("Matemáticas");5cursosAna.add("Física");6mapaEstudiantesCursos.put("Ana", cursosAna);7
8List<String> cursosCarlos = new ArrayList<>();9cursosCarlos.add("Literatura");10cursosCarlos.add("Historia");11mapaEstudiantesCursos.put("Carlos", cursosCarlos);
Inserción de múltiples elementos
Para insertar todos los elementos de un Map
en otro, usamos putAll()
:
1Map<String, Double> preciosProductosA = new HashMap<>();2preciosProductosA.put("Laptop", 999.99);3preciosProductosA.put("Smartphone", 599.99);4
5Map<String, Double> preciosProductosB = new HashMap<>();6preciosProductosB.putAll(preciosProductosA);7preciosProductosB.put("Tablet", 299.99);
Obtención de elementos
Para obtener un valor asociado a una clave, usamos el método get()
:
1List<String> cursosAna = mapaEstudiantesCursos.get("Ana");2if (cursosAna != null && !cursosAna.isEmpty()) {3 String primerCursoAna = cursosAna.get(0);4 System.out.println("Primer curso de Ana: " + primerCursoAna);5}
Valor por defecto
Si no estamos seguros de que una clave exista, podemos usar getOrDefault()
, que nos permite especificar un valor por defecto en caso de que la clave no exista:
1List<String> cursosJuan = mapaEstCursos.getOrDefault("Juan", new ArrayList<>());2System.out.println("Cursos de Juan: " + cursosJuan);
Aquí podríamos realizar alguna acción si la lista de cursos está vacía, como agregar un mensaje de error.
Verificación de contenido
Para verificar si un Map
contiene una clave o un valor específico:
1boolean contieneAna = mapaEstudiantesCursos.containsKey("Ana");2
3boolean contieneFisica = false;4for (List<String> cursos : mapaEstudiantesCursos.values()) {5 if (cursos.contains("Física")) {6 contieneFisica = true;7 break;8 }9}
Iteración sobre un Map
Existen varias formas de iterar sobre un Map
:
Usando entrySet()
1for (Map.Entry<String, List<String>> entrada : mapaEstudiantesCursos.entrySet()) {2 System.out.println(entrada.getKey() + " está inscrito en: " + entrada.getValue());3}
Usando keySet()
y valores
1for (String estudiante : mapaEstudiantesCursos.keySet()) {2 List<String> cursos = mapaEstudiantesCursos.get(estudiante);3 System.out.println(estudiante + " está tomando " + cursos.size() + " cursos");4}
Eliminación de elementos
Para eliminar un elemento específico:
1List<String> cursosEliminados = mapaEstudiantesCursos.remove("Carlos");
Para eliminar todos los elementos de un Map
:
1mapaEstudiantesCursos.clear();
Reemplazo de valores
El método replace()
solo reemplaza el valor si la clave ya existe:
1List<String> nuevosCursosAna = new ArrayList<>();2nuevosCursosAna.add("Química");3nuevosCursosAna.add("Biología");4mapaEstudiantesCursos.replace("Ana", nuevosCursosAna);
Además de reemplazar, este método también devuelve el valor anterior asociado a la clave.
Operaciones adicionales
Tamaño del Map
1int numeroEstudiantes = mapaEstudiantesCursos.size();
Verificar si está vacío
1boolean estaVacio = mapaEstudiantesCursos.isEmpty();
Ejemplo práctico
Veamos un ejemplo más complejo que combina varias de estas operaciones:
1import java.util.*;2
3public class SistemaCalificaciones {4 private Map<String, Map<String, Double>> calificacionesEstudiantes;5
6 public SistemaCalificaciones() {7 calificacionesEstudiantes = new HashMap<>();8 }9
10 public void agregarCalificacion(String estudiante, String materia, Double calificacion) {11 // Si no existe el estudiante, se crea un nuevo Map para sus calificaciones12 if (!calificacionesEstudiantes.containsKey(estudiante)) {13 calificacionesEstudiantes.put(estudiante, new HashMap<>());14 }15 // Se agrega la calificación al Map correspondiente16 calificacionesEstudiantes.get(estudiante).put(materia, calificacion);17 }18
19 public Double obtenerPromedio(String estudiante) {20 Map<String, Double> calificaciones = calificacionesEstudiantes.get(estudiante);21 if (calificaciones == null || calificaciones.isEmpty()) {22 return 0.0;23 }24 double suma = 0.0;25 int contador = 0;26 for (Double calificacion : calificaciones.values()) {27 suma += calificacion;28 contador++;29 }30 return suma / contador;31 }32
33 public void imprimirCalificaciones() {34 for (String estudiante : calificacionesEstudiantes.keySet()) {35 System.out.println(estudiante + ":");36 Map<String, Double> calificaciones = calificacionesEstudiantes.get(estudiante);37 for (String materia : calificaciones.keySet()) {38 Double calificacion = calificaciones.get(materia);39 System.out.println(" " + materia + ": " + calificacion);40 }41 System.out.println(" Promedio: " + obtenerPromedio(estudiante));42 }43 }44
45 public static void main(String[] args) {46 SistemaCalificaciones sistema = new SistemaCalificaciones();47
48 sistema.agregarCalificacion("Ana", "Matemáticas", 9.5);49 sistema.agregarCalificacion("Ana", "Física", 8.7);50 sistema.agregarCalificacion("Carlos", "Literatura", 7.8);51 sistema.agregarCalificacion("Carlos", "Historia", 8.9);52
53 sistema.imprimirCalificaciones();54 }55}
Detalles de funcionamiento del ejemplo
El Sistema de Calificaciones implementado en este ejemplo utiliza una estructura de datos basada en Maps
anidados para gestionar las calificaciones de los estudiantes. Con los componentes principales:
-
Estructura de datos:
1private Map<String, Map<String, Double>> calificacionesEstudiantes;- Es un
Map
donde la clave es el nombre del estudiante (String
). - El valor es otro
Map
que representa las calificaciones del estudiante. - En el
Map
interno, la clave es el nombre de la materia (String
) y el valor es la calificación (Double
).
- Es un
-
Métodos principales:
a.
agregarCalificacion
:- Verifica si el estudiante ya existe en el
Map
principal. - Si no existe, crea un nuevo
Map
para ese estudiante. - Agrega la calificación al
Map
del estudiante.
b.
obtenerPromedio
:- Recupera el
Map
de calificaciones del estudiante. - Calcula el promedio sumando todas las calificaciones y dividiendo por el número de materias.
c.
imprimirCalificaciones
:- Itera sobre todos los estudiantes en el
Map
principal. - Para cada estudiante, itera sobre sus materias y calificaciones.
- Imprime cada calificación y calcula el promedio.
- Verifica si el estudiante ya existe en el
-
Flujo de ejecución:
- Se crea una instancia de
SistemaCalificaciones
. - Se agregan calificaciones para diferentes estudiantes y materias.
- Se llama al método
imprimirCalificaciones
para mostrar todos los datos.
- Se crea una instancia de
Con respecto a TreeMap
, esta implementación ordena las claves de manera natural o según un comparador personalizado. Por otro lado, HashMap
no garantiza ningún orden específico. Esto lo veremos al iterar sobre los elementos de un Map
.