11 - Almacenamiento de HashMap y clave-valor
Aprende a almacenar y recuperar datos usando pares clave-valor.
Un HashMap almacena datos en pares clave-valor, al igual que un diccionario del mundo real. Buscas una palabra (clave) para encontrar su definición (valor). Esto es perfecto para datos del jugador, propiedades de objetos y configuraciones.
Conceptos básicos del HashMap
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// Crea un HashMap (String keys, Integer values)
HashMap<String, Integer> playerLevels = new HashMap<>();
// agrega pares clave-valor
playerLevels.put("Alice", 10);
playerLevels.put("Bob", 15);
playerLevels.put("Charlie", 8);
// obtener un valor por su clave
int aliceLevel = playerLevels.get("Alice"); // 10
System.out.println("Alice es nivel " + aliceLevel);
}
}| HashMap | ArrayList |
|---|---|
| Sin ordenar | Ordenado por el índice (0, 1, 2...) |
| Acceso por clave (puede ser de cualquier tipo) | Acceso por posición |
| Útil para buscar valores | Útil para listas de elementos |
| Cada clave es única | Puede tener duplicados |
// ArrayList - acceso por número
ArrayList<String> players = new ArrayList<>();
players.add("Alice");
String player = players.get(0); // Obtener el primer jugador
// HashMap - acceso por nombre
HashMap<String, Integer> levels = new HashMap<>();
levels.put("Alice", 10);
int level = levels.get("Alice"); // Obtener el nivel de AliceMétodos comunes del HashMap
Agregar y Actualizar
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100); // Añadir una nueva entrada
scores.put("Bob", 150);
scores.put("Alice", 200); // Actualizar una entrada existente (Alice ahora tendrá 200)Obtener Valores
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100);
int score = scores.get("Alice"); // 100
Integer missing = scores.get("Dave"); // null (no existe)
// Obtener con valor predeterminado
int score2 = scores.getOrDefault("Dave", 0); // 0 (devuelve el valor predeterminado)Comprobación de Claves/Valores
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100);
boolean hasAlice = scores.containsKey("Alice"); // Verdadero
boolean hasDave = scores.containsKey("Dave"); // Falso
boolean has100 = scores.containsValue(100); // Verdadero
boolean has200 = scores.containsValue(200); // FalsoEliminación de Entradas
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100);
scores.put("Bob", 150);
scores.remove("Alice"); // Eliminar por entrada
System.out.println(scores); // {Bob=150}
scores.clear(); // Eliminar todo
System.out.println(scores); // {}Comprobación de Tamaño y Vacío
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100);
int size = scores.size(); // 1
boolean empty = scores.isEmpty(); // FalsoRecorriendo un HashMap
Recorrer Claves
HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100);
scores.put("Bob", 150);
scores.put("Charlie", 75);
for (String name : scores.keySet()) {
System.out.println(name);
}
// Salida: Alice, Bob, Charlie (el orden puede variar)Recorrer Valores
for (Integer score : scores.values()) {
System.out.println(score);
}
// Salida: 100, 150, 75 (el orden puede variar)Recorrer Claves y Valores
for (String name : scores.keySet()) {
int score = scores.get(name);
System.out.println(name + ": " + score);
}
// O usando un entrySet (más eficiente)
for (var entry : scores.entrySet()) {
String name = entry.getKey();
int score = entry.getValue();
System.out.println(name + ": " + score);
}¡HashMap no mantiene el orden de inserción! Si necesitas mantener el orden, usa LinkedHashMap:
import java.util.LinkedHashMap;
LinkedHashMap<String, Integer> orderedScores = new LinkedHashMap<>();
orderedScores.put("Alice", 100);
orderedScores.put("Bob", 150);
orderedScores.put("Charlie", 75);
// Se imprimirá en orden de inserción
for (String name : orderedScores.keySet()) {
System.out.println(name);
}
// Salida: Alice, Bob, Charlie (orden garantizado)Ejemplos Prácticos
Sistema de Estadísticas del Jugador
import java.util.HashMap;
public class PlayerStats {
private HashMap<String, Integer> stats;
public PlayerStats() {
this.stats = new HashMap<>();
// Inicializar las estadísticas predeterminadas
stats.put("health", 100);
stats.put("mana", 50);
stats.put("strength", 10);
stats.put("defense", 5);
stats.put("speed", 8);
}
public int getStat(String statName) {
return stats.getOrDefault(statName, 0);
}
public void setStat(String statName, int value) {
stats.put(statName, value);
}
public void modifyStat(String statName, int amount) {
int current = getStat(statName);
stats.put(statName, current + amount);
}
public void displayStats() {
System.out.println("=== Player Stats ===");
for (var entry : stats.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
// Forma de utilizarlo
public class Main {
public static void main(String[] args) {
PlayerStats stats = new PlayerStats();
stats.displayStats();
stats.modifyStat("strength", 5);
stats.modifyStat("health", -20);
System.out.println("\nAfter modifications:");
stats.displayStats();
}
}Base de Datos de las Propiedades de un Objeto
import java.util.HashMap;
public class ItemDatabase {
private HashMap<String, HashMap<String, Object>> items;
public ItemDatabase() {
this.items = new HashMap<>();
}
public void addItem(String itemName) {
HashMap<String, Object> properties = new HashMap<>();
properties.put("damage", 0);
properties.put("durability", 100);
properties.put("rarity", "Common");
properties.put("stackable", true);
items.put(itemName, properties);
}
public void setProperty(String itemName, String property, Object value) {
if (items.containsKey(itemName)) {
items.get(itemName).put(property, value);
}
}
public Object getProperty(String itemName, String property) {
if (items.containsKey(itemName)) {
return items.get(itemName).get(property);
}
return null;
}
public void displayItem(String itemName) {
if (!items.containsKey(itemName)) {
System.out.println("Item not found!");
return;
}
System.out.println("=== " + itemName + " ===");
HashMap<String, Object> props = items.get(itemName);
for (var entry : props.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
// Forma de utilizarlo
public class Main {
public static void main(String[] args) {
ItemDatabase db = new ItemDatabase();
db.addItem("Iron Sword");
db.setProperty("Iron Sword", "damage", 15);
db.setProperty("Iron Sword", "rarity", "Uncommon");
db.displayItem("Iron Sword");
}
}Gestor de Configuración
import java.util.HashMap;
public class GameConfig {
private HashMap<String, String> settings;
public GameConfig() {
this.settings = new HashMap<>();
loadDefaults();
}
private void loadDefaults() {
settings.put("difficulty", "normal");
settings.put("musicVolume", "50");
settings.put("sfxVolume", "50");
settings.put("renderDistance", "10");
settings.put("showFPS", "false");
}
public String getSetting(String key) {
return settings.getOrDefault(key, "");
}
public void setSetting(String key, String value) {
settings.put(key, value);
System.out.println("Set " + key + " to " + value);
}
public int getIntSetting(String key) {
String value = getSetting(key);
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return 0;
}
}
public boolean getBooleanSetting(String key) {
return "true".equalsIgnoreCase(getSetting(key));
}
public void displaySettings() {
System.out.println("=== Game Settings ===");
for (var entry : settings.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}Inventario del Jugador con Cantidades
import java.util.HashMap;
public class Inventory {
private HashMap<String, Integer> items;
private int maxSlots;
public Inventory(int maxSlots) {
this.items = new HashMap<>();
this.maxSlots = maxSlots;
}
public boolean addItem(String itemName, int quantity) {
if (items.size() >= maxSlots && !items.containsKey(itemName)) {
System.out.println("Inventory full!");
return false;
}
int current = items.getOrDefault(itemName, 0);
items.put(itemName, current + quantity);
System.out.println("Added " + quantity + "x " + itemName);
return true;
}
public boolean removeItem(String itemName, int quantity) {
if (!items.containsKey(itemName)) {
System.out.println("Don't have that item!");
return false;
}
int current = items.get(itemName);
if (current < quantity) {
System.out.println("Not enough " + itemName);
return false;
}
if (current == quantity) {
items.remove(itemName);
} else {
items.put(itemName, current - quantity);
}
System.out.println("Removed " + quantity + "x " + itemName);
return true;
}
public int getQuantity(String itemName) {
return items.getOrDefault(itemName, 0);
}
public boolean hasItem(String itemName) {
return items.containsKey(itemName);
}
public void displayInventory() {
System.out.println("\n=== Inventory (" + items.size() + "/" + maxSlots + " slots) ===");
if (items.isEmpty()) {
System.out.println("Empty");
} else {
for (var entry : items.entrySet()) {
System.out.println(entry.getKey() + " x" + entry.getValue());
}
}
}
}
// Forma de utilizarlo
public class Main {
public static void main(String[] args) {
Inventory inv = new Inventory(10);
inv.addItem("Wood", 64);
inv.addItem("Stone", 32);
inv.addItem("Wood", 20); // Se suma a la cantidad ya existente
inv.displayInventory();
inv.removeItem("Wood", 50);
inv.displayInventory();
}
}Gestor del Tiempo de Reutilización
HashMap con Objetos Personalizados
Almacena tus propias clases como un valor:
public class Player {
private String name;
private int level;
private int health;
public Player(String name, int level) {
this.name = name;
this.level = level;
this.health = 100;
}
// Getters and setters...
@Override
public String toString() {
return name + " (Lv. " + level + ", HP: " + health + ")";
}
}
public class Main {
public static void main(String[] args) {
HashMap<String, Player> players = new HashMap<>();
players.put("player1", new Player("Alice", 10));
players.put("player2", new Player("Bob", 15));
// Obtener y usar un jugador
Player alice = players.get("player1");
System.out.println(alice);
}
}HashMaps anidados
Los HashMaps pueden contener otros HashMaps:
// Almacenar múltiples propiedades por jugador
HashMap<String, HashMap<String, Integer>> playerData = new HashMap<>();
// Agregar jugador con estadísticas
HashMap<String, Integer> aliceStats = new HashMap<>();
aliceStats.put("level", 10);
aliceStats.put("health", 100);
aliceStats.put("mana", 50);
playerData.put("Alice", aliceStats);
// Acceder a datos anidados
int aliceLevel = playerData.get("Alice").get("level");
System.out.println("Nivel de Alice: " + aliceLevel);Ejercicios Prácticos
-
Agenda telefónica: Crea una agenda telefónica que almacena nombres y números de teléfono. Añadir métodos a:
- Añadir contacto
- Encontrar un número por el nombre
- Borrar contacto
- Mostrar todos los contactos
-
Gestor de calificaciones: Almacena los nombres de los estudiantes y sus calificaciones. Añadir métodos a:
- Añadir un estudiante con su calificación
- Actualizar calificación
- Calcular la media de la clase
- Encontrar la calificación más alta
-
Cuentapalabras: Escribe un programa que cuenta las veces que aparece cada palabra en una frase haciendo uso de un HashMap.
-
Tienda de objetos: Crea una tienda donde los objetos tengan nombre y precio. Añadir métodos a:
- Añadir un objeto con precio
- Obtener el precio del objeto
- Aplicar un descuento a todos los objetos
- Mostrar todos los objetos y precios