Hytale Modding
Основи Java

11 - HashMap та Key-Value сховище

Навчіться зберігати та отримувати дані за допомогою пар Key-Value.

HashMap зберігає дані у парах key-value, як у реальному словнику. Ви шукаєте слово (key), щоб знайти його значення (value). Це ідеально підходить для даних гравця, властивостей предметів та налаштувань конфігурації.

Основи HashMap

import java.util.HashMap;

public class Main {
    public static void main(String[] args) {
        // Створити HashMap (String keys, Integer values)
        HashMap<String, Integer> playerLevels = new HashMap<>();
        
        // Додати пари key-value
        playerLevels.put("Анна", 10);
        playerLevels.put("Богдан", 15);
        playerLevels.put("Василь", 8);
        
        // Отримати значення за ключем
        int aliceLevel = playerLevels.get("Анна");  // 10
        
        System.out.println("Анна на рівні " + aliceLevel);
    }
}
HashMap проти ArrayList
HashMapArrayList
Без сортуванняСортовано за індексом (0, 1, 2...)
Доступ за ключем (може бути будь-яким типом)Доступ за позицією
Корисно для пошуку значеньКорисно для списків елементів
Кожен ключ є унікальнимМоже мати дублікати
// ArrayList - доступ за числом
ArrayList<String> players = new ArrayList<>();
players.add("Анна");
String player = players.get(0);  // Отримати першого гравця

// HashMap - доступ за ім'ям
HashMap<String, Integer> levels = new HashMap<>();
levels.put("Анна", 10);
int level = levels.get("Alice");  // Отримати рівень Анни

Загальні методи HashMap

Додавання та оновлення

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

scores.put("Анна", 100);     // Додати нове значення
scores.put("Богдан", 150);
scores.put("Анна", 200);     // Оновити чинне (Анна тепер 200)

Отримання значень

HashMap<String, Integer> scores = new HashMap<>();
scores.put("Анна", 100);

int score = scores.get("Анна");        // 100
Integer missing = scores.get("Данило");   // null (не існує)

// Отримати зі значенням за умовчанням 
int score2 = scores.getOrDefault("Данило", 0);  // 0 (повертає значення за умовчанням )

Перевірка ключів/значень

HashMap<String, Integer> scores = new HashMap<>();
scores.put("Анна", 100);

boolean hasAlice = scores.containsKey("Анна");    // true
boolean hasDave = scores.containsKey("Данило");      // false

boolean has100 = scores.containsValue(100);        // true
boolean has200 = scores.containsValue(200);        // false

Видалення записів

HashMap<String, Integer> scores = new HashMap<>();
scores.put("Анна", 100);
scores.put("Богдан", 150);

scores.remove("Анна");           // Видалити за ключем
System.out.println(scores);       // {Богдан=150}

scores.clear();                   // Видалити все
System.out.println(scores);       // {}

Розмір і порожня перевірка

HashMap<String, Integer> scores = new HashMap<>();
scores.put("Анна", 100);

int size = scores.size();         // 1
boolean empty = scores.isEmpty(); // false

Перебір HashMap

Перебір ключів

HashMap<String, Integer> scores = new HashMap<>();
scores.put("Анна", 100);
scores.put("Богдан", 150);
scores.put("Василь", 75);

for (String name : scores.keySet()) {
    System.out.println(name);
}
// Вивід: Анна, Богдан, Василь(порядок може варіюватися)

Перебір значень

for (Integer score : scores.values()) {
    System.out.println(score);
}
// Вивід: 100, 150, 75 (порядок може варіюватися)

Перебір ключів і значень

for (String name : scores.keySet()) {
    int score = scores.get(name);
    System.out.println(name + ": " + score);
}

// Або використовуючи entrySet (більш ефективний)
for (var entry : scores.entrySet()) {
    String name = entry.getKey();
    int score = entry.getValue();
    System.out.println(name + ": " + score);
}
Порядок HashMap

HashMap не підтримує порядок вставки! Якщо вам потрібен порядок, використовуйте LinkedHashMap:

import java.util.LinkedHashMap;

LinkedHashMap<String, Integer> orderedScores = new LinkedHashMap<>();
orderedScores.put("Анна", 100);
orderedScores.put("Богдан", 150);
orderedScores.put("Василь", 75);

// Друкуватиметься в порядку вставки
for (String name : orderedScores.keySet()) {
    System.out.println(name);
}
// Output: Анна, Богдан, Василь(гарантований порядок)

Практичні приклади

Система статистики гравців

import java.util.HashMap;

public class PlayerStats {
    private HashMap<String, Integer> stats;
    
    public PlayerStats() {
        this.stats = new HashMap<>();
        // Ініціалізувати статистику за замовчуванням
        stats.put("Здоров'я", 100);
        stats.put("Мана", 50);
        stats.put("Сила", 10);
        stats.put("Захист", 5);
        stats.put("Швидкість", 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("=== Статистика гравця===");
        for (var entry : stats.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

// Використання
public class Main {
    public static void main(String[] args) {
        PlayerStats stats = new PlayerStats();
        stats.displayStats();
        
        stats.modifyStat("Сила", 5);
        stats.modifyStat("Здоров'я", -20);
        
        System.out.println("ісля модифікації:");
        stats.displayStats();
    }
}

База даних властивостей елементів

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("Шкода", 0);
        properties.put("Витривалість", 100);
        properties.put("Рідкісність", "Звичайна");
        properties.put("Стакований", 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("Пркдмет знайдено!");
            return;
        }
        
        System.out.println("=== " + itemName + " ===");
        HashMap<String, Object> props = items.get(itemName);
        for (var entry : props.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

// Використання
public class Main {
    public static void main(String[] args) {
        ItemDatabase db = new ItemDatabase();
        
        db.addItem("Залізний меч");
        db.setProperty("Залізний меч", "Шкода", 15);
        db.setProperty("Залізний меч", "Рідкісність", "Невичайна");
        
        db.displayItem("Залізний меч");
    }
}

Менеджер конфігурації

import java.util.HashMap;

public class GameConfig {
    private HashMap<String, String> settings;
    
    public GameConfig() {
        this.settings = new HashMap<>();
        loadDefaults();
    }
    
    private void loadDefaults() {
        settings.put("Важкість", "normal");
        settings.put("Гучність музики", "50");
        settings.put("Гучність звуку", "50");
        settings.put("Відстань рендеру", "10");
        settings.put("Показати FPS", "false");
    }
    
    public String getSetting(String key) {
        return settings.getOrDefault(key, "");
    }
    
    public void setSetting(String key, String value) {
        settings.put(key, value);
        System.out.println("Встановити " + key + " : " + 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("=== Налаштування гри===");
        for (var entry : settings.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
    }
}

Player Inventory with Quantities

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());
            }
        }
    }
}

// Usage
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);  // Adds to existing
        
        inv.displayInventory();
        
        inv.removeItem("Wood", 50);
        inv.displayInventory();
    }
}

Cooldown Manager

import java.util.HashMap;

public class CooldownManager {
    private HashMap<String, Long> cooldowns;
    
    public CooldownManager() {
        this.cooldowns = new HashMap<>();
    }
    
    public void startCooldown(String ability, long durationMs) {
        long endTime = System.currentTimeMillis() + durationMs;
        cooldowns.put(ability, endTime);
        System.out.println(ability + " on cooldown for " + (durationMs / 1000) + " seconds");
    }
    
    public boolean isOnCooldown(String ability) {
        if (!cooldowns.containsKey(ability)) {
            return false;
        }
        
        long endTime = cooldowns.get(ability);
        long now = System.currentTimeMillis();
        
        if (now >= endTime) {
            cooldowns.remove(ability);
            return false;
        }
        
        return true;
    }
    
    public long getRemainingTime(String ability) {
        if (!isOnCooldown(ability)) {
            return 0;
        }
        
        long endTime = cooldowns.get(ability);
        long now = System.currentTimeMillis();
        return (endTime - now) / 1000;  // Return seconds
    }
    
    public boolean useAbility(String ability, long cooldownSeconds) {
        if (isOnCooldown(ability)) {
            long remaining = getRemainingTime(ability);
            System.out.println(ability + " is on cooldown (" + remaining + "s remaining)");
            return false;
        }
        
        System.out.println("Used " + ability + "!");
        startCooldown(ability, cooldownSeconds * 1000);
        return true;
    }
}

HashMap with Custom Objects

Store your own classes as values:

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));
        
        // Get and use player
        Player alice = players.get("player1");
        System.out.println(alice);
    }
}

Nested HashMaps

HashMaps can contain other HashMaps:

// Store multiple properties per player
HashMap<String, HashMap<String, Integer>> playerData = new HashMap<>();

// Add player with stats
HashMap<String, Integer> aliceStats = new HashMap<>();
aliceStats.put("level", 10);
aliceStats.put("health", 100);
aliceStats.put("mana", 50);
playerData.put("Alice", aliceStats);

// Access nested data
int aliceLevel = playerData.get("Alice").get("level");
System.out.println("Alice's level: " + aliceLevel);

Practice Exercises

  1. Phone Book: Create a phone book that stores names and phone numbers. Add methods to:

    • Add contact
    • Find number by name
    • Delete contact
    • Display all contacts
  2. Grade Manager: Store student names and grades. Create methods to:

    • Add student with grade
    • Update grade
    • Calculate class average
    • Find highest grade
  3. Word Counter: Write a program that counts how many times each word appears in a sentence using a HashMap.

  4. Item Shop: Create a shop where items have names and prices. Add methods to:

    • Add item with price
    • Get item price
    • Apply discount to all items
    • Display all items and prices