1. Tập hợp các cặp khóa-giá trị.

Một tập hợp các cặp khóa-giá trị

Trong Java, một bộ sưu tập thú vị khác (nói chung) là Map. Đôi khi cấu trúc dữ liệu này còn được gọi là từ điển.

Nó tương tự như bộ Setsưu tập, nhưng nó lưu trữ một tập hợp các "cặp" phần tử chứ không phải là một tập hợp các phần tử, Mỗi cặp trong một Mapbao gồm hai phần tử: "khóa" và "giá trị".

Giả sử bạn muốn chương trình của mình lưu tên nhân viên và tiền lương của họ, hoặc tên đồng nghiệp của bạn và tuổi của họ. Sau đó, bạn sẽ cần một bảng như thế này:

Tên Tuổi
elon 21
jeff 22
Hóa đơn 48
Warren ?

Mỗi hàng chứa một vài giá trị. Chúng tôi sẽ coi tên là khóa của cặp và tuổi là giá trị của cặp .

Toàn bộ các cặp này là bản đồ của chúng tôi ( Map).

Khóa của một cặp có thể là bất kỳ thứ gì ngoại trừ null. Các khóa phải là duy nhất: một bản đồ không thể chứa hai khóa giống hệt nhau.


2. HashMaplớp học

Lớp HashMaplà loại Maptập hợp phổ biến nhất. Một mặt, nó rất giống với HashSet và có tất cả các phương thức của nó. Mặt khác, nó giống như một danh sách ( ArrayList) có thể sử dụng các từ (hoặc bất kỳ thứ gì khác) làm chỉ số của nó.

Bạn có thể tạo một HashMapcâu lệnh bằng cách sử dụng như thế này:

HashMap<KeyType, ValueType> name = new HashMap<KeyType, ValueType>();

Đâu KeyTypelà loại khóa trong các cặp được lưu trữ và ValueTypelà loại giá trị trong các cặp được lưu trữ trong bộ HashMapsưu tập.

Lớp HashMapnày có các phương thức như thế này:

Phương pháp Sự miêu tả
void put(KeyType key, ValueType value)
Thêm cặp ( key, value) vào bộ sưu tập
ValueType get(KeyType key)
Trả về giá trị được liên kết với một khóa.
boolean containsKey(KeyType key)
Kiểm tra xem một khóa có tồn tại trong bộ sưu tập hay không
boolean containsValue(ValueType value)
Kiểm tra sự tồn tại của một giá trị trong bộ sưu tập
ValueType remove(KeyType key)
Xóa một phần tử khỏi bộ sưu tập
void clear()
Xóa bộ sưu tập, loại bỏ tất cả các phần tử
int size()
Trả về số cặp khóa-giá trị trong bộ sưu tập
Set<KeyType> keySet()
Trả về bộ khóa trong bộ sưu tập
Collection<ValueType> values()
Trả về một tập hợp chứa các phần tử của tập hợp
Set<Map.Entry<KeyType, ValueType>> entrySet()
Trả về một bộ ( Set) gồm tất cả các cặp ( Map.Entry) trong bộ sưu tập.

Thêm phần tử vào mộtHashMap

Các yếu tố được thêm vào bản đồ dưới dạng các cặp bằng put()phương pháp. Khóa được truyền dưới dạng đối số đầu tiên và giá trị được truyền dưới dạng đối số thứ hai.

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Elon", 21);
map.put("Jeff", 22);
map.put("Bill", 48);
map.put("Warren", null);

Khi thêm một cặp khóa-giá trị, nếu khóa đã tồn tại trong bộ sưu tập thì giá trị cũ sẽ được thay thế bằng giá trị mới.

Hành vi này tạo ra HashMapmột mảng hoặc danh sách có chỉ số là từ ( String) thay vì số.

Quan trọng:

Hầu hết mọi loại đều có thể là KeyType hoặc ValueType. Có một số yêu cầu bổ sung nhỏ đối với KeyType và bạn sẽ tìm hiểu về chúng khi bạn nghiên cứu các bộ sưu tập chi tiết hơn trong nhiệm vụ Bộ sưu tập Java.



3. Tập con của a HashMap: tập các khóa

Giả sử chúng ta chỉ muốn hiển thị tất cả các mục trong a HashMaptrên màn hình. Chung ta se lam như thê nao? Để làm điều này, chúng ta cần biết cách đi qua tất cả các mục trong tệp HashMap. Điều này có thể được thực hiện theo nhiều cách.

Cách dễ nhất là lặp qua các phím

HashMapcác mục nhập không được đánh số liên tục, vì vậy vòng lặp có bộ đếm sẽ không hoạt động ở đây. Nhưng chúng ta có thể lấy một tập hợp các khóa bằng keySet()phương thức này và bạn đã biết cách lặp qua một tập hợp:

Mã số Sự miêu tả
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Elon", 21);
map.put("Jeff", 22);
map.put("Bill", 48);
map.put("Warren", null);

for (String key: map.keySet())
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}






Lặp lại các khóa của map

Nhận giá trị được liên kết với khóa

Phương keySet()thức trả về một bộ khóa. Bạn có thể sử dụng bộ này theo hai cách:

ký hiệu nhỏ gọn ký hiệu dài
for (String key: map.keySet())
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}
Set<String> keys = map.keySet();

for (String key: keys)
{
   Integer value = map.get(key);
   System.out.println(key + " --> " + value);
}


4. Lặp lại các cặp khóa-giá trị

Ngoài ra còn có một cách phức tạp hơn: bạn có thể chuyển đổi a Mapthành một tập hợp các cặp khóa-giá trị , rồi lặp qua các phần tử của tập hợp, như chúng ta đã học.

Bộ HashMapsưu tập có lớp trình trợ giúp lưu trữ cặp khóa-giá trị. Nó trông gần như thế này:

class Entry<KeyType, ValueType>
{
   private KeyType key;
   private ValueType value;

   public KeyType getKey()
   {
      return this.key;
   }

   public ValueType getValue()
   {
      return this.value;
   }
}

Kết quả của việc gọi entrySet()phương thức trên một đối tượng sẽ là :HashMap<KeyType, ValueType>Set<Entry<KeyType, ValueType>>

Set<Entry<KeyType, ValueType>> name = map.entrySet();

Ở đây chúng ta có Setlớp chung với một tham số kiểu, đến lượt nó là một kiểu chung ( Entry) với hai tham số kiểu.

Người mới bắt đầu rất dễ nhầm lẫn về điều này. Nhưng một khi bạn tìm ra nó, bạn có thể viết mã như sau:

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("Elon", 21);
map.put("Jeff", 22);
map.put("Bill", 48);
map.put("Warren", null);

Set<Map.Entry<String, Integer>> entries = map.entrySet();
for(Map.Entry<String, Integer> pair: entries)
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Điều đó nói rằng, mã này có thể được đơn giản hóa một chút:

Đầu tiên, bạn có thể bỏ qua việc tạo một biến riêng cho entriesvà thay vào đó gọi entrySet()phương thức trực tiếp bên trong forvòng lặp:

for(Map.Entry<String, Integer> pair: map.entrySet())
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Thứ hai, bạn có thể sử dụng vartoán tử được giới thiệu gần đây để tự động suy ra loại của cặp khóa-giá trị :

for(var pair: map.entrySet())
{
   String key = pair.getKey();
   Integer value = pair.getValue();
   System.out.println(key + " --> " + value);
}

Không tệ nhỉ?



5. So sánh ArrayListHashMap

A HashMaprất giống với an ArrayListcho phép sử dụng các chuỗi (hoặc các loại khác) làm chỉ mục (các khóa).

Nếu bạn sử dụng Integercho các phím trong a HashMap, thì nó càng trở nên giống với a ArrayList. Hãy so sánh:

Mã với ArrayList<String> Mã với HashMap<Integer, String>
ArrayList<String> list = new ArrayList<String>();

list.add("Greetings");
list.add("Hello");

String s = list.get(0);
list.set(0, s + "!");

for (String item: list)
{
   System.out.println(item);
}
HashMap<Integer, String> map = new HashMap<Integer, String>();

map.put(0, "Greetings");
map.put(1, "Hello");

String s = map.get(0);
map.put(0, s + "!");

for (String item: map.values())
{
   System.out.println(item);
}