Chuyển tới nội dung chính

HashMap trong Java

HashMap là một lớp trong Java Collections Framework, cung cấp một cấu trúc dữ liệu bảng băm cho phép lưu trữ các cặp khóa-giá trị. HashMap không đảm bảo thứ tự của các phần tử và cho phép một khóa null và nhiều giá trị null.

1. Khai báo và khởi tạo HashMap

Khai báo HashMap

// Khai báo HashMap với khóa và giá trị là String
HashMap<String, String> map;

// Khai báo HashMap với khóa là Integer và giá trị là String
HashMap<Integer, String> studentMap;

// Khai báo HashMap với khóa là String và giá trị là Object
HashMap<String, Object> dataMap;

Khởi tạo HashMap

// Khởi tạo HashMap rỗng
HashMap<String, String> map = new HashMap<>();

// Khởi tạo HashMap với dung lượng ban đầu
HashMap<String, String> map = new HashMap<>(16);

// Khởi tạo HashMap với dung lượng và hệ số tải
HashMap<String, String> map = new HashMap<>(16, 0.75f);

// Khởi tạo HashMap từ Map khác
Map<String, String> otherMap = new HashMap<>();
HashMap<String, String> map = new HashMap<>(otherMap);

2. Các phương thức cơ bản

Thêm phần tử

HashMap<String, String> map = new HashMap<>();

// Thêm một cặp khóa-giá trị
map.put("name", "John");

// Thêm nhiều cặp khóa-giá trị
map.putAll(Map.of(
"age", "25",
"city", "New York"
));

// Thêm nếu khóa chưa tồn tại
map.putIfAbsent("email", "[email protected]");

Xóa phần tử

HashMap<String, String> map = new HashMap<>();
map.put("name", "John");
map.put("age", "25");

// Xóa theo khóa
map.remove("name");

// Xóa theo khóa và giá trị
map.remove("age", "25");

// Xóa tất cả phần tử
map.clear();

Truy cập phần tử

HashMap<String, String> map = new HashMap<>();
map.put("name", "John");

// Lấy giá trị theo khóa
String value = map.get("name");

// Lấy giá trị mặc định nếu khóa không tồn tại
String defaultValue = map.getOrDefault("age", "Unknown");

// Kiểm tra khóa tồn tại
boolean exists = map.containsKey("name");

// Kiểm tra giá trị tồn tại
boolean hasValue = map.containsValue("John");

3. Các phương thức tiện ích

Kích thước và kiểm tra

HashMap<String, String> map = new HashMap<>();

// Lấy số lượng phần tử
int size = map.size();

// Kiểm tra HashMap rỗng
boolean isEmpty = map.isEmpty();

// Lấy tất cả khóa
Set<String> keys = map.keySet();

// Lấy tất cả giá trị
Collection<String> values = map.values();

// Lấy tất cả cặp khóa-giá trị
Set<Map.Entry<String, String>> entries = map.entrySet();

Cập nhật giá trị

HashMap<String, Integer> map = new HashMap<>();
map.put("count", 1);

// Cập nhật giá trị nếu khóa tồn tại
map.computeIfPresent("count", (key, value) -> value + 1);

// Cập nhật giá trị nếu khóa không tồn tại
map.computeIfAbsent("count", key -> 1);

// Cập nhật giá trị và trả về giá trị cũ
Integer oldValue = map.replace("count", 2);

Duyệt HashMap

HashMap<String, String> map = new HashMap<>();
map.put("name", "John");
map.put("age", "25");

// Duyệt theo khóa
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}

// Duyệt theo giá trị
for (String value : map.values()) {
System.out.println(value);
}

// Duyệt theo cặp khóa-giá trị
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}

// Sử dụng forEach
map.forEach((key, value) ->
System.out.println(key + ": " + value));

4. Ví dụ thực tế

Quản lý danh sách học sinh

public class StudentManager {
private HashMap<String, Student> students;

public StudentManager() {
students = new HashMap<>();
}

public void addStudent(String id, Student student) {
students.put(id, student);
}

public Student getStudent(String id) {
return students.get(id);
}

public void updateGrade(String id, double grade) {
students.computeIfPresent(id, (key, student) -> {
student.setGrade(grade);
return student;
});
}

public void removeStudent(String id) {
students.remove(id);
}

public List<Student> getStudentsByGrade(double minGrade) {
return students.values().stream()
.filter(student -> student.getGrade() >= minGrade)
.collect(Collectors.toList());
}
}

Cache đơn giản

public class SimpleCache<K, V> {
private HashMap<K, V> cache;
private int maxSize;

public SimpleCache(int maxSize) {
this.cache = new HashMap<>();
this.maxSize = maxSize;
}

public void put(K key, V value) {
if (cache.size() >= maxSize) {
// Xóa phần tử đầu tiên
K firstKey = cache.keySet().iterator().next();
cache.remove(firstKey);
}
cache.put(key, value);
}

public V get(K key) {
return cache.get(key);
}

public boolean contains(K key) {
return cache.containsKey(key);
}

public void clear() {
cache.clear();
}
}

5. Best Practices

  1. Chỉ định kiểu dữ liệu khi khai báo

    // Không nên
    HashMap map = new HashMap();

    // Nên
    HashMap<String, String> map = new HashMap<>();
  2. Sử dụng getOrDefault thay vì kiểm tra null

    // Không nên
    String value = map.get("key");
    if (value == null) {
    value = "default";
    }

    // Nên
    String value = map.getOrDefault("key", "default");
  3. Sử dụng entrySet() khi cần cả khóa và giá trị

    // Không nên
    for (String key : map.keySet()) {
    String value = map.get(key);
    // Xử lý key và value
    }

    // Nên
    for (Map.Entry<String, String> entry : map.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();
    // Xử lý key và value
    }

6. Lỗi thường gặp

  1. NullPointerException

    HashMap<String, String> map = null;
    map.put("key", "value"); // Lỗi: map chưa được khởi tạo
  2. ConcurrentModificationException

    HashMap<String, String> map = new HashMap<>();
    map.put("key", "value");

    for (String key : map.keySet()) {
    map.remove(key); // Lỗi: sửa đổi trong khi duyệt
    }
  3. ClassCastException

    HashMap<Object, Object> map = new HashMap<>();
    map.put("key", "value");

    // Lỗi: không thể ép kiểu String thành Integer
    Integer value = (Integer) map.get("key");