Trong map, kiểu dữ liệu của cả key và value đều do người dùng xác định. Quyền truy cập dựa trên key vào các mục map cho phép các khả năng xử lý map cụ thể khác nhau: từ việc nhận một value theo key đến việc lọc riêng biệt các key và value. Trên trang này, chúng tôi cung cấp các mô tả về các thao tác xử lý map từ thư viện chuẩn.
Nội dung chính
1. Truy xuất các key và value
Để lấy một value từ một map, bạn phải cung cấp key của nó làm đối số của hàm get(). Cú pháp viết tắt [key] cũng được hỗ trợ. Nếu không tìm thấy key đã cho, nó sẽ trả về null. Ngoài ra còn có hàm getValue() với cách hoạt động hơi khác: nó ném ra một ngoại lệ nếu key không được tìm thấy trong map. Ngoài ra, bạn có hai tùy chọn khác để xử lý việc key không có mặt trong map:
- Hàm getOrElse() thao tác theo cách tương tự như đối với list: các value cho các key không tồn tại được trả về từ hàm lambda đã cho.
- Hàm getOrDefault() trả về value mặc định được chỉ định nếu không tìm thấy key.
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.get("one"))
println(numbersMap["one"])
println(numbersMap.getOrDefault("four", 10))
println(numbersMap["five"]) // null
//numbersMap.getValue("six") // exception!
Để thực hiện các thao tác trên tất cả các key hoặc tất cả các value của map, bạn có thể truy xuất chúng từ các thuộc tính keys và values tương ứng. Keys là một tập hợp tất cả các key của map và values là tập hợp tất cả các value của map.
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.keys)
println(numbersMap.values)
2. Chọn lọc
Bạn có thể chọn lọc các map với hàm filter() giống như các collection khác. Khi gọi hàm filter() trên map, hãy chuyển cho nó một vị từ với Pair làm đối số. Việc này cho phép bạn sử dụng cả key và value trong vị từ lọc.
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap)
Cũng có hai cách cụ thể để lọc map: theo key và theo value. Đối với mỗi cách thì đều có một hàm: filterKeys()và filterValues(). Cả hai hàm này đều trả về một map mục nhập mới phù hợp với vị từ đã cho. Vị từ cho filterKeys() chỉ kiểm tra các phần tử key, vị từ cho filterValues() chỉ kiểm tra các value.
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredKeysMap = numbersMap.filterKeys { it.endsWith("1") }
val filteredValuesMap = numbersMap.filterValues { it < 10 }
println(filteredKeysMap)
println(filteredValuesMap)
3. Các toán tử cộng và trừ
Do quyền truy cập vào các phần tử dựa trên key, các toán tử plus( +) và minus(-) thao tác với map theo một cách khác so với khi chúng thao tác với các collection khác. Toán tử plus trả về một Map chứa các phần tử của cả hai toán hạng của nó: một Map ở bên trái và ở bên phải là một Pair hoặc một Map khác. Khi toán hạng bên phải chứa các mục nhập có các key hiện diện ở Map phía bên trái, thì map trong kết quả chứa các mục nhập từ phía bên phải.
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap + Pair("four", 4))
println(numbersMap + Pair("one", 10))
println(numbersMap + mapOf("five" to 5, "one" to 11))
Toán tử minus tạo một Map từ các mục nhập của một Map ở bên trái ngoại trừ các mục có key của toán hạng bên phải. Vì vậy, toán hạng bên phải có thể là một key đơn hoặc một collection gồm các key: list, set, v.v.
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap - "one")
println(numbersMap - listOf("two", "four"))
Để biết chi tiết về cách sử dụng toán tử plusAssign( +=) và minusAssign( -=) trên map có thể thay đổi, hãy xem Các thao tác ghi map bên dưới.
4. Các thao tác ghi map
Map có thể thay đổi cung cấp các thao tác ghi map cụ thể. Các thao tác này cho phép bạn thay đổi nội dung map bằng cách sử dụng quyền truy cập dựa trên key vào các value.
Có một số quy tắc xác định các thao tác ghi trên map:
- Các value có thể được cập nhật. Đổi lại, các key thì không bao giờ thay đổi: khi bạn thêm một mục nhập, key của nó sẽ không đổi.
- Đối với mỗi key, luôn có một value duy nhất được liên kết với nó. Bạn có thể thêm và xóa toàn bộ mục nhập.
Dưới đây là mô tả về các chức năng thư viện tiêu chuẩn cho các thao tác ghi có sẵn trên map có thể thay đổi.
4.1. Thêm và cập nhật các mục nhập
Để thêm cặp key-value mới vào map có thể thay đổi, hãy sử dụng hàm put(). Khi một mục mới được đưa vào một LinkedHashMap (triển khai map mặc định), nó sẽ được thêm vào để nó xuất hiện cuối cùng khi lặp qua map. Trong các map được sắp xếp, vị trí của các phần tử mới được xác định theo thứ tự các key của chúng.
val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap.put("three", 3)
println(numbersMap)
Để thêm nhiều mục cùng một lúc, hãy sử dụng hàm putAll(). Đối số của nó có thể là một Map hoặc một nhóm các Pair: Iterable, Sequence, hoặc Array.
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.putAll(setOf("four" to 4, "five" to 5))
println(numbersMap)
Cả hai hàm put()và putAll() đều ghi đè các value nếu các key đã cho đã tồn tại trong map. Do đó, bạn có thể sử dụng chúng để cập nhật value của các mục trong map.
val numbersMap = mutableMapOf("one" to 1, "two" to 2)
val previousValue = numbersMap.put("one", 11)
println("value associated with 'one', before: $previousValue, after: ${numbersMap["one"]}")
println(numbersMap)
Bạn cũng có thể thêm các mục mới vào map bằng cách sử dụng các dạng toán tử viết tắt. Có hai cách:
- Toán tử plusAssign( +=).
- các dấu hiệu toán tử [] cho hàm put().
val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap["three"] = 3 // calls numbersMap.put("three", 3)
numbersMap += mapOf("four" to 4, "five" to 5)
println(numbersMap)
Khi được gọi với key có trong map, các toán tử sẽ ghi đè value của các mục nhập tương ứng.
4.1 Xóa mục nhập
Để xóa mục nhập khỏi map có thể thay đổi, hãy sử dụng hàm remove(). Khi gọi hàm remove(), bạn có thể truyền một key hoặc cả cặp key-value làm đối số. Nếu bạn chỉ định cả key và value, phần tử có key này sẽ chỉ bị xóa nếu value của nó khớp với đối số thứ hai.
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.remove("one")
println(numbersMap)
numbersMap.remove("three", 4) //doesn't remove anything
println(numbersMap)
Bạn cũng có thể xóa các mục nhập khỏi map có thể thay đổi bằng các key hoặc value của chúng. Để thực hiện việc này, hãy gọi hàm remove() trên các key hoặc value của map trong đó bạn cung cấp key hoặc value của một mục nhập làm đối số. Khi được gọi trên các value, hàm remove() chỉ xóa mục nhập đầu tiên có value đã cho.
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3, "threeAgain" to 3)
numbersMap.keys.remove("one")
println(numbersMap)
numbersMap.values.remove(3)
println(numbersMap)
Toán tử minusAssign( -=) cũng có sẵn cho các map có thể thay đổi.
val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap -= "two"
println(numbersMap)
numbersMap -= "five" //doesn't remove anything
println(numbersMap)
Tài liệu từ cafedev:
- Full series tự học Kotlin từ cơ bản tới nâng cao tại đây nha.
- Ebook về Kotlin tại đây.
- Các series tự học lập trình khác
Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:
Chào thân ái và quyết thắng!