Hash Map Trong Java Hoạt Động Như Thế Nào?
Hiện nay có rất nhiều cách để tổ chức dữ liệu trong chương trình, điển hình trong số đó là HashMap. Với mức độ thông dụng ngày càng cao, HashMap đang là lựa chọn của nhiều lập trình viên trong các dự án của họ.
Vậy HashMap thật ra là gì và nó hoạt động như thế nào, hãy cùng mình tìm hiểu qua bài viết này nhé.
HashMap là gì?
Interface Map
Trước khi nói đến HashMap, chúng ta cần phải hiểu sơ lược về sự hình thành của nó, hay nói cách khác là sự bắt nguồn của HashMap. Nó xuất phát từ một Map interface (java.util.Map), interface này biểu diễn sự ánh xạ giữa một trường gọi là "khóa" và một trường gọi là "giá trị", mô hình của nó như sau.
Các tính năng đặc trưng của thành phần trong hệ thống Map
- Có 2 class thực thi trực tiếp Map interface bao gồm
- Hashtable: Không chứa giá trị
null
, hỗ trợ đồng bộ nhưng đã lỗi thời. - Hashmap: Cho phép chứa giá trị
null
, không hỗ trợ đồng bộ, với đặc điểm đặc trưng là thứ tự lặp (iteration order) không theo một quy tắc nào (random).
- Hashtable: Không chứa giá trị
- Class TreeMap thực thi gián tiếp qua các interface mở rộng của interface Map, với đặc điểm đặc trưng là tự động sắp xếp giá trị (theo thứ tự tự nhiên).
- Class LinkedHashMap extends từ class HashMap, với đặc điểm đặc trưng là thứ tự lặp là thứ tự ban đầu của các Entry (thứ tự thêm vào).
Xem thêm: Interface là gì, Iteration là gì, Implement và Extends
HashMap hoạt động dựa trên nguyên lý nào?
Hashing là gì? : Hashing là một thuật toán có thể áp dụng cho bất kỳ đối tượng nào, và khi thực hiện, hashing sẽ trả về một giá trị (kiểu số nguyên) duy nhất đại diện cho đối tượng đó. Giá trị số nguyên duy nhất này được gọi là mã băm (hash code).
Các thông tin về sinh viên sau khi qua một thuật toán Hash
Map interface không extends bất kỳ interface nào khác từ thư viện Collection, nên cách hoạt động của nó cũng khác hẳn so với các interface khác trong thư viện Collection. HashMap lưu trữ dữ liệu theo các cặp (viết tắt là K-V). Mỗi cặp được lưu trữ trong 1 đối tượng gọi là Entry, và Entry này được lưu trong một table tuân theo nguyên tắc Hashing
static class Entry<K,V> implements Map.Entry<K,V>
{
//Khóa của đối tượng (K)
final K key;
//Giá trị tại K (V)
V value;
//Con trỏ tới Entry(đối tượng) kế tiếp
Entry<K,V> next;
//HashCode của K
int hash;
}
Chi tiết về đặc điểm chính của HashMap:
- HashMap không thể chứa các key(K) trùng lặp
- HashMap cho phép value(V) =
null
và/hoặc key(K) =null
- HashMap là một bộ sưu tập không có thứ tự. Nó không đảm bảo bất kỳ thứ tự cụ thể của các phần tử, hay nói dễ hiểu hơn là thứ tự khi duyệt của HashMap không theo một nguyên tắc nào.
- HashMap không hỗ trợ đồng bộ hóa. Bạn phải đồng bộ hóa rõ ràng các sửa đổi đồng thời với HashMap.
Thao tác cơ bản với HashMap
1. Tạo mới
Cách tạo một đối tượng HashMap mới:
- Import thư viện:
import java.util.HashMap;
- Tạo một HashMap với cú pháp:
HashMap<K,V> {name}=new HashMap<>();
Dưới đây là một số ví dụ
//Tạo mới một HashMap bao gồm Key(String) và Value(String)
HashMap<String,String> hashmap0=new HashMap<>();
//Tạo mới một HashMap bao gồm Key(Integer) và Value(Float)
HashMap<Integer,Float> hashMap1 = new HashMap<>();
//Tạo mới một HashMap bao gồm Key(String) và Value(Double), có kích thước bằng 10
HashMap<String,Double> hashMap2 = new HashMap<>(10);
//Khai báo 1 HashMap được tạo thành từ 1 Collection khác
HashMap<Float, Integer> hashMap4 = new HashMap<>(new TreeMap<>());
2. Thêm Entry(K-V) vào HashMap
Phương thức : put(Object key, Object value);
Thêm một cặp giá trị vào HashMap vừa tạo, kiểu dữ liệu của K và V phải giống với kiểu dữ liệu được khai báo trong HashMap lúc vừa khởi tạo.
hashmap.put("Hardware", "Phần cứng");
hashmap.put("Software", "Phần mềm");
hashmap.put("College", "Trường Đại Học");
hashmap.put("Programer", "Lập Trình Viên");
hashmap.put("Compile", "Biên Dịch");
hashmap.put("Error", "Lỗi");
Kiểu dữ liệu của khóa trong trường hợp này (key:K) là String
và kiểu dữ liệu của giá trị (value:V) cũng là String
.
3. Sửa Value của một Entry trong HashMap
Phương thức: replace(key, newValue);
Dùng để thay đổi giá trị của một khóa K bất kỳ đã tồn tại bên trong HashMap
//Thêm Entry vào HashMap
hashmap.put("DoanDucTin", "Class_SE1403");
//Thay đổi value của Entry có key là "DoanDucTin"
hashmap.replace("DoanDucTin", "NewClass_SE1401");
4. Xóa Một Entry(K-V) ra khỏi HashMap
Phương thức: remove(key);
Dùng để xóa một Entry ra khỏi HashMap dựa vào khóa K
//Thêm Entry vào HashMap
hashmap.put("Error", "Lỗi");
//Xóa Entry ra khỏi HashMap dựa vào key (K)
hashmap.remove("Error");
5. Hiển thị toàn bộ Entry của HashMap ra màn hình
Cách 1: Sử dụng EntrySet
Phương thức này sẽ trả về 1 Set bao gồm các Entry có trong HashMap (cú pháp khai báo Set: Set<Map.Entry<K,V>> set = hashmap.entrySet();
)
//Tạo một Set lưu các EntrySet của HashMap
Set<Map.Entry<String, String>> setHashMap = hashmap.entrySet();
//Sử dụng một vòng lặp for để iterator qua toàn bộ Entry vừa được lưu vào Set
for (Map.Entry<String,String> i:setHashMap){
System.out.println(i.getKey()+" --> "+i.getValue());
}
In thử HashMap ra màn hình
Có thể dùng thêm hashMap.values();
để hiển thị toàn bộ giá trị trong HashMap hoặc hashMap.keySet();
để hiển thị toàn bộ key trong HashMap
//In toàn bộ key ra màn hình
for (String i:hashmap.keySet()){
System.out.println(i);
}
//In toàn bộ giá trị ra màn hình
for (String i:hashmap.values()){
System.out.println(i);
}
In thử HashMap ra màn hình
Cách 2: Sử dụng Iterator
Iterator là một đối tượng có khả năng duyệt qua phần tử, để sử dụng trước hết chúng ta cần phải import thư viện java.util.Iterator
của Java
//Khai báo một đối tượng Iterator từ entrySet của hashmap
Iterator<Map.Entry<String, String>> iterator = hashmap.entrySet().iterator();
//Duyệt qua toàn bộ phần tử trong Iterator để in kết quả ra màn hình
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
6. Lấy value khi biết key
Phương thức: get(key);
Trả về một đối tượng value(V) tương ứng tới key(K)
//Thêm Entry vào HashMap
hashmap.put("DoanDucTin", "Class_SE1403");
//Lấy giá trị tương ứng với khóa "DoanDucTin"
System.out.println(hashmap.get("DoanDucTin"));
//Console -->:Class_SE1403
Một số phương thức khác
Phương Thức | Mô tả sơ lược |
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) | Kiểm tra nếu HashMap chứa một phần tử có khóa được chỉ định. |
boolean containsValue(Object value) | Kiểm tra nếu HashMap chứa một phần tử có giá trị được chỉ định. |
boolean isEmpty() | Kiểm tra HashMap trống hay không. |
void putAll(Map t) | Sao chép các phần tử của Map vào HashMap. |
int size() | Trả về số phần tử đang tồn tại bên trong HashMap. |
Ứng dụng của hashMap
- Dùng làm từ điển:
HashMap sử dụng trường Key để lưu từ Tiếng Anh và trường giá trị là nghĩa của từ đó trong Tiếng Việt
- Ngoài ra, HashMap còn được ứng dụng nhiều trong các chương trình và đặc biệt là ứng dụng trong quản lý các đối tượng mà đối tượng đó sử dụng một khóa (nhằm mục đích định danh) và trả về một thông tin về đối tượng đó
Tổng Kết
Trong bài này, mình đã giới thiệu cho các bạn những đặc điểm, cách hoạt động cũng như các phương thức thường dùng trong HashMap, hi vọng sau bài viết các bạn có thể có thêm được nhiều kiến thức mới. HashMap hiện nay đang được nhiều nhà tuyển dụng sử dụng để đặt các câu hỏi phỏng vấn nhằm kiểm tra trình độ chuyên môn và sự hiểu biết của bạn, vì vậy ngoài HashMap ra, các bạn nên tìm hiểu và tổng hợp cho chính bản thân mình nhiều kiến thức nhất có thể nhé, chúc các bạn thành công.
Project mẫu sử dụng HashMap của mình (Từ Điển): tải về tại đây