Hashmap là một cấu trúc dữ liệu trong Java dùng để dữ liệu dưới các cặp key-value, trong đó khóa là duy nhất và không trùng lặp. Nó thuộc về gói java.util và là một phần quan trọng của các chương trình Java do cung cấp tính năng tối ưu để lấy và chèn các phần tử.

1. Hashmap trong Java là gì?

Hashmap là một lớp nằm trong package java.util và implement interface Map. Nó là một cấu trúc dữ liệu lưu dữ liệu dưới dạng key-value, trong đó mỗi khóa là duy nhất và không thể trùng lặp. Hashmap cho phép lưu giá trị khóa là null và chỉ có duy nhất một khóa là null, trong khi đó bất kỳ giá trị nào trong value set có thể là null. Lớp này không đảm bảo thứ tự lưu trữ và có thể thay đổi kích thước động khi số lượng các cặp key-value thay đổi.

1.1. Hierarchy của lớp HashMap trong Java

HashMap hierachy

1.2. Khai báo lớp HashMap trong Java

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

Trong đó:

  • K: kiểu lưu trữ key
  • V: kiểu của các giá trị được ánh xạ

1.3. Đặc điểm của HashMap

Một HashMap là một cấu trúc dữ liệu được sử dụng để lưu trữ và khai thác dữ liệu dựa trên các giá trị khóa. Dưới đây là một số đặc điểm của HashMap:

  • Thời gian truy cập nhanh: thuật toán truy cập phần tử của HashMap có độ phức tạp là O(1), do đó thời gian truy xuất phần tử của HashMap là nhanh và đều đặn
  • Sử dụng thuật toán băm: HashMap sử dụng một thuật toán băm để ánh xạ khóa cho chỉ mục trong mảng. Điều này cho phép map có thể được sử dụng để tìm kiếm nhanh trên chính nó.
  • Lưu trữ các giá trị dưới dạng các cặp khóa - giá trị: Từng phần tử trong map chứa một cặp key-value. Các giá trị khóa được sử dụng để tìm kiếm các giá trị tương ứng với nó.
  • Các phần tử không được sắp xếp: HashMap không được sắp xếp thứ tự, điều này có nghĩa là thứ tự các phần tử được ghi lần lượt vào trong map sẽ không được ghi lại. Tuy nhiên, LinkedHashMap là một dạng HashMap nhưng có duy trì thứ tự phần tử.
  • Cho phép các phần tử trùng lặp: HashMap cho phép lưu trữ nhiều giá trị trùng lặp, nhưng không trùng lặp các khóa. Nếu một giá trị khóa trùng lặp được thêm vào, giá trị tương ứng trước đó với khóa sẽ được ghi đè.
  • Thread-unsafe: HashMap không thread-safe, nếu nhiều luồng truy cập vào cùng một HashMap tại cùng một thời điểm có thể dẫn tới việc dữ liệu bị sai. Nếu bạn cần thread safety khi sử dụng map, chúng ta có thể sử dụng ConcurrentHashMap.
  • Dung lượng chứa và tỉ lệ tải: HashMap có dung lượng là số lượng phần tử mà nó có thể chứa và tỉ lệ tải, điều này giúp nó có thể định lượng được mức độ đầy mà một HashMap có thể đạt được trước khi nó được chia lại dung lượng.

Xem thêm bài viết về chủ đề ngôn ngữ lập trình Java:

- Tìm hiểu về Singleton pattern trong Java

- Tìm hiểu về design pattern factory trong java

- Xử lý timezone trong Java

2. Constructor của HashMap trong Java

HashMap cung cấp 4 constructors và access modifier của các constructor này đều là public, dưới đây là các constructor của HashMap:

  • HashMap(): constructor mặc định của HashMap, khi sử dụng sẽ khởi tạo một đối tượng HashMap có kích thước là 16 và loadFactor là 0.75 Ví dụ: HashMap<String, String> map = new HashMap();
  • HashMap(int capacity): khởi tạo một đối tượng HashMap có kích thước là capacityloadFactor là 0.75 Ví dụ: HashMap<String, String> map = new HashMap(5);
  • HashMap(int capacity, float loadFactor): khởi tạo một đối tượng có kích thước là capacity và loadFactor là loadFactor Ví dụ: HashMap<String, String> map = new HashMap(5, 0.5f);
  • HashMap(Map map): tạo một đối tượng HashMap với cùng mappings với map được truyền vào Ví dụ: HashMap<String, String> map = new HashMap(map1);

3. Phương thức của lớp HashMap trong Java

Sau đây là các phương thức của lớp HashMap hay được sử dụng trong Java:

Phương thứcMô tả
void clear()Xóa tất cả các phần tử của HashMap.
Object clone()Trả về một bản copy của HashMap.
boolean containsKey(Object key)Trả về true nếu HashMap chứa một phần tử có key được chỉ định.
boolean containsValue(Object value)Trả về true nếu HashMap chứa một phần tử có giá trị (value) được chỉ định.
Set entrySet()Trả về Collection view các ánh xạ có trong HashMap.
Object get(Object key)Trả về giá trị của key được chỉ định.
boolean isEmpty()Trả về true nếu HashMap trống.
Set keySet()Trả về một Set interface chứa tất cả các key của HashMap.
Object put(Object key, Object value)Thêm một cặp key-value vào HashMap.
void putAll(Map t)Sao chép các phần tử của Map được chỉ định vào HashMap.
Object remove(Object key)Xóa một phần tử có key được chỉ định ra khởi HashMap.
int size()Trả về số phần tử của HashMap.

4. Thao tác với HashMap trong Java

4.1. Khởi tạo một HashMap

Để khai báo một HashMap, chúng ta cần phải import gói thư viện java.util.HashMap của Java. Cú pháp import như sau:

import java.util.HashMap;
 
public class Main {
    public static void main(String[] args) {
        
        HashMap<String, String> map = new HashMap();
    }
}

4.2. Duyệt và hiển thị các phần tử trong HashMap

  • Sử dụng vòng lặp for để duyệt các phần tử trong map: Chúng ta sẽ sử dụng keySet() của HashMap để lặp các key của HashMap, sau đó sẽ sử dụng key này để lấy ra giá trị tương ứng được lưu trữ trong HashMap.
public class HashMapExample {
 
    public static void main(String args[]) {
        // init hashMap
        HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
        // add elements to hashMap
        hashMap.put(1, "Java");
        hashMap.put(3, "C++");
        hashMap.put(2, "PHP");
        hashMap.put(4, "Python");
        
        // travel in keySet and get its associated value
        for (Integer key : hashMap.keySet()) {
            System.out.println(key + " : " + hashMap.get(key));
        }
    }

}
  • Sử dụng interface Map.Entry để duyệt: ở đây chúng ta sử dụng phương thức entrySet() để duyệt các phần tử của HashMap, phương thức này trả về một đối tượng Map.Entry.
public class HashMapExample {
    public static void main(String args[]) {
        // init map
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        // add elements to map
        map.put(1, "Java");
        map.put(3, "C++");
        map.put(2, "PHP");
        map.put(4, "Python");

        // get entrySet and travel in set
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }
}

4.3. Truy cập phần tử của HashMap

Phương thức get(key) trả về giá trị của phần tử có key đã chỉ định:

public class HashMapExample {
 
    public static void main(String args[]) {
        // init hashMap
        HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
        // add elements to hashMap
        hashMap.put(1, "Java");
        hashMap.put(3, "C++");
        hashMap.put(2, "PHP");
        hashMap.put(4, "Python");

        // show map
        System.out.println("Entry at key 1 has value: " + hashMap.get(1));
        System.out.println("Entry at key 2 has value: " + hashMap.get(2));
    }
}

4.4. Cập nhật phần tử trong HashMap

Sử dụng phương thức put() để thêm phần tử, đồng thời bạn cũng có thể sử dụng chính phương thức này để cập nhật phần tử tại vị trí chỉ định của HashMap

public class HashMapExample {

    public static void main(String args[]) {
            // init hashMap
            HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
            // add elements to the map
            hashMap.put(1, "Java");
            hashMap.put(3, "C++");
            hashMap.put(2, "PHP");
            hashMap.put(4, "Python");

            // show map
            System.out.println(hashMap);
            

            hashMap.put(4, "VueJS");
            // show map
            System.out.println(hashMap);
        }
    }
}

4.5. Xóa phần tử trong HashMap

Bạn có thể sử dụng phương thức remove() để xóa một phần tử, hoặc phương thức clear() để xóa hoàn toàn các phần tử của một HashMap.

public class HashMapExample {
 
    public static void main(String args[]) {
        // init map
        HashMap<Integer, String> hashMap = new HashMap<Integer, String>();
        // add elements to the map
        hashMap.put(1, "Java");
        hashMap.put(3, "C++");
        hashMap.put(2, "PHP");
        hashMap.put(4, "Python");

        // show map
        System.out.println(hashMap);

        // remove element at key 4
        hashMap.remove(4);

        // show map
        System.out.println(hashMap);

        // delete all the map
        hashMap.clear();

        // show map
        System.out.println(hashMap);
    }
}

Tạm kết HashMap là một công cụ hữu ích và mạnh mẽ trong Java, cho phép bạn lưu trữ và quản lý dữ liệu theo kiểu cặp khóa-giá trị. Tuy nhiên, việc truy cập vào HashMap từ nhiều luồng có thể gây ra rủi ro dẫn đến deadlock, bạn nên cân nhắc sử dụng ConcurrentHashMap nếu có nhiều luồng truy xuất vào map của mình. Sử dụng HashMap đúng cách có thể giúp bạn tận dụng tối đa sức mạnh của HashMap và xây dựng các ứng dụng Java đáng tin cậy và hiệu quả.

Stringee API  là bộ giải pháp cung cấp các tính năng như gọi thoại, gọi video, tin nhắn chat, SMS hay tổng đài chăm sóc khách hàng (CSKH) có thể được nhúng trực tiếp vào các ứng dụng/website của doanh nghiệp nhanh chóng. Điều này giúp tiết kiệm đến 80% thời gian và chi phí cho doanh nghiệp, trong khi nếu tự phát triển các tính năng này có thể mất từ 1 - 3 năm.

Mời quý bạn đọc đăng ký dùng thử và nhận tư vấn tại đây: