Hướng dẫn và ví dụ Java SortedMap
1. SortedMap
SortedMap là một interface con của Map, vì vậy nó có đầy đủ các đặc điểm của Map. Điều khác biệt là các khoá (key) của SortedMap được sắp xếp tăng dần theo thứ tự tự nhiên của chúng hoặc theo một Comparator được cung cấp. Comparator thường được cung cấp tại thời điểm tạo đối tượng SortedMap.
public interface SortedMap<K,V> extends Map<K,V>
- Map
- ConcurrentMap
- ConcurrentNavigableMap
- NavigableMap
Sau đây là so sánh giữa Map và SortedMap:
Map<K,V> | SortedMap<K,V> NavigableMap<K,V> |
Không cho phép trùng lặp khoá. | |
Có thể cho phép khoá null và các giá trị null. | |
Thứ tự của các khoá không được đảm bảo. | Các khoá được xắp xếp theo thứ tự tăng dần dựa trên thứ tự tự nhiên của chúng hoặc theo một Comparator được cung cấp. |
Tất cả các khoá của SortedMap phải là kiểu Comparable (có thể so sánh) hoặc bạn phải cung cấp một Comparator (bộ so sánh) cho SortedMap để nó so sánh các khoá với nhau. Ngược lại, ClassCastException sẽ bị ném ra.
Comparator<K>
Nếu một Comparator được cung cấp cho SortedMap, hai khoá sẽ được so sánh với nhau bằng phương thức comparator.compare(key1,key2). Tính nhất quán với bằng (consistent with equals) phải được tuân thủ. Điều này có nghĩa là nếu comparator.compare(key1,key2)=0 thì key1.equals(key2)=true (Đúng với mọi khoá trong SortedMap).
- Hướng dẫn và ví dụ Java Comparator
Comparable<K>
Nếu Comparator không được cung cấp cho SortedMap. Tất cả các khoá của SortedMap phải là kiểu Comparable để chúng có thể so sánh với nhau. Các khoá sẽ được so sánh với nhau theo quy tắc key1.equals(key2). Tính nhất quán bằng (equals consistance) cần được tuân thủ. Điều này có nghĩa là key1.equals(key2) và key2.equals(key1) phải trả về cùng một giá trị.
- Tìm hiểu về Java System.identityHashCode, Object.hashCode và Object.equals
- Hướng dẫn và ví dụ Java Comparable
- TreeMap
- HashMap
- IdentityHashMap
- WeakHashMap
- LinkedHashMap
- EnumMap
- ConcurrentHashMap
- ConcurrentSkipListMap
2. Examples
Lớp String thi hành interface Comparable, vì vậy các đối tượng String có thể so sánh với nhau, và có thể được sử dụng như các khoá cho SortedMap.
SortedMapEx1.java
package org.o7planning.sortedmap.ex;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
public class SortedMapEx1 {
public static void main(String[] args) {
// Create a SortedMap object.
SortedMap<String, Integer> map = new TreeMap<String, Integer>();
map.put("B", 100);
map.put("A", 200);
map.put("F", 400);
map.put("D", 500);
map.put("E", 100);
System.out.println("--- keySet ---");
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.println(key + " --> " + map.get(key));
}
System.out.println("--- entrySet ---");
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
for (Map.Entry<String,Integer> entry: entrySet) {
System.out.println(entry.getKey() + " --> " + entry.getValue());
}
}
}
Output:
--- keySet ---
A --> 200
B --> 100
D --> 500
E --> 100
F --> 400
--- entrySet ---
A --> 200
B --> 100
D --> 500
E --> 100
F --> 400
Chú ý: Về cơ bản, TreeMap không cho phép khoá null, trừ khi bạn cung cấp cho nó một Comparator hỗ trợ việc so sánh null với các các giá trị khác. Bạn có thể tìm thấy ví dụ về TreeMap với khoá null trong bài viết sau:
Ví dụ: Lớp OrderLineId dưới đây thi hành interface Comparable, vì vậy các đối tượng OrderLineId có thể so sánh được với nhau:
OrderLineId.java
package org.o7planning.beans;
public class OrderLineId implements Comparable<OrderLineId> {
private int orderId;
private int line;
public OrderLineId(int orderId, int line) {
this.orderId = orderId;
this.line = line;
}
public int getOrderId() {
return orderId;
}
public int getLine() {
return line;
}
@Override
public int compareTo(OrderLineId other) {
if (other == null) {
return 1; // this > other
}
if (this.orderId != other.orderId) {
return this.orderId - other.orderId;
}
return this.line - other.line;
}
}
SortedMapEx2.java
package org.o7planning.sortedmap.ex;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.o7planning.beans.OrderLineId;
public class SortedMapEx2 {
public static void main(String[] args) {
// OrderLineId --> String productName.
SortedMap<OrderLineId, String> sortedMap = new TreeMap<>();
OrderLineId k21 = new OrderLineId(2, 1);
OrderLineId k12 = new OrderLineId(1, 2);
OrderLineId k11 = new OrderLineId(1, 1);
OrderLineId k22 = new OrderLineId(2, 2);
OrderLineId k31 = new OrderLineId(3, 1);
OrderLineId k23 = new OrderLineId(2, 3);
sortedMap.put(k21, "Samsung a71");
sortedMap.put(k12, "IPhone 12");
sortedMap.put(k11, "Samsung a51");
sortedMap.put(k22, "IPhone 11");
sortedMap.put(k31, "IPhone 7");
sortedMap.put(k23, "Samsung a51");
Set<OrderLineId> keys = sortedMap.keySet();
for(OrderLineId key: keys) {
String productName = sortedMap.get(key);
System.out.println("OrderId: " + key.getOrderId() //
+ " / Line: " + key.getLine() + " --> " + productName);
}
}
}
Output:
OrderId: 1 / Line: 1 --> Samsung a51
OrderId: 1 / Line: 2 --> IPhone 12
OrderId: 2 / Line: 1 --> Samsung a71
OrderId: 2 / Line: 2 --> IPhone 11
OrderId: 2 / Line: 3 --> Samsung a51
OrderId: 3 / Line: 1 --> IPhone 7
Ví dụ: Lớp OrderLineKey dưới đây không thi hành interface Comparable, vì vậy các đối tượng OrderLineKey không thể so sánh được với nhau. Trong trường hợp này bạn cần cung cấp một Comparator cho SortedMap.
OrderLineKey.java
package org.o7planning.beans;
public class OrderLineKey {
private int orderId;
private int line;
public OrderLineKey(int orderId, int line) {
this.orderId = orderId;
this.line = line;
}
public int getOrderId() {
return orderId;
}
public int getLine() {
return line;
}
}
SortedMapEx3.java
package org.o7planning.sortedmap.ex;
import java.util.Comparator;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.o7planning.beans.OrderLineKey;
public class SortedMapEx3 {
public static void main(String[] args) {
// Comparator.
OrderLineKeyComparator comparator = new OrderLineKeyComparator();
// Creaate SortedMap with a Comparator.
// OrderLineKey --> String productName.
SortedMap<OrderLineKey, String> sortedMap = new TreeMap<>(comparator);
OrderLineKey k21 = new OrderLineKey(2, 1);
OrderLineKey k12 = new OrderLineKey(1, 2);
OrderLineKey k11 = new OrderLineKey(1, 1);
OrderLineKey k22 = new OrderLineKey(2, 2);
OrderLineKey k31 = new OrderLineKey(3, 1);
OrderLineKey k23 = new OrderLineKey(2, 3);
sortedMap.put(k21, "Samsung a71");
sortedMap.put(k12, "IPhone 12");
sortedMap.put(k11, "Samsung a51");
sortedMap.put(null, "<Nothing>");
sortedMap.put(k22, "IPhone 11");
sortedMap.put(k31, "IPhone 7");
sortedMap.put(k23, "Samsung a51");
Set<OrderLineKey> keys = sortedMap.keySet();
for (OrderLineKey key : keys) {
String productName = sortedMap.get(key);
if(key == null) {
System.out.println("Null Key --> " + productName);
} else {
System.out.println("OrderId: " + key.getOrderId() //
+ " / Line: " + key.getLine() + " --> " + productName);
}
}
}
}
// This comparator supports null comparison.
class OrderLineKeyComparator implements Comparator<OrderLineKey> {
@Override
public int compare(OrderLineKey o1, OrderLineKey o2) {
if (o1 == o2) {
return 0;
}
if (o1 == null) {
return -1; // o1 < o2.
}
if (o2 == null) {
return 1; // o1 > o2
}
int d = o1.getOrderId() - o2.getOrderId();
if (d != 0) {
return d;
}
return o1.getLine() - o2.getLine();
}
}
Output:
Null Key --> <Nothing>
OrderId: 1 / Line: 1 --> Samsung a51
OrderId: 1 / Line: 2 --> IPhone 12
OrderId: 2 / Line: 1 --> Samsung a71
OrderId: 2 / Line: 2 --> IPhone 11
OrderId: 2 / Line: 3 --> Samsung a51
OrderId: 3 / Line: 1 --> IPhone 7
3. SortedMap Methods
SortedMap Methods
Comparator<? super K> comparator();
SortedMap<K,V> subMap(K fromKey, K toKey);
SortedMap<K,V> headMap(K toKey);
SortedMap<K,V> tailMap(K fromKey);
K firstKey();
K lastKey();
// Inherited from Map
Set<K> keySet();
Set<Map.Entry<K, V>> entrySet();
Collection<V> values();
...
4. comparator()
Comparator<? super K> comparator()
Trả về Comparator được sử dụng để sắp xếp các khóa trong SortedMap này, hoặc null nếu SortedMap này sử dụng thứ tự tự nhiên của các khóa.
7. subMap(K fromKey, K toKey)
SortedMap<K,V> subMap(K fromKey, K toKey)
Trả về chế độ xem của một phần của SortedMap này bao gồm các ánh xạ với khoá nằm trong khoảng từ fromKey đến toKey (fromKey =< key < toKey). (Nếu fromKey và toKey bằng nhau, SortedMap trả về là rỗng).
SortedMap trả về có liên hệ với SortedMap hiện tại, các thay đổi trên SortedMap này có ảnh hưởng tới SortedMap kia và ngược lại.
SortedMap_subMap_ex1.java
package org.o7planning.sortedmap.ex;
import java.util.SortedMap;
import java.util.TreeMap;
public class SortedMap_subMap_ex1 {
public static void main(String[] args) {
SortedMap<String, String> myMap = new TreeMap<>();
myMap.put("A", "VA");
myMap.put("B", "VB");
myMap.put("C", "VC");
myMap.put("D", "VD");
myMap.put("E", "VE");
// A Sub Map
SortedMap<String, String> subMap = myMap.subMap("B", "C1");
System.out.println(" -- subMap --");
for (String s : subMap.keySet()) {
System.out.println(s + " --> " + subMap.get(s));
}
subMap.put("B1", "VB1");
subMap.put("B2", "VB2");
System.out.println(" -- subMap (after putting some mappings to subMap) --");
for (String s : subMap.keySet()) {
System.out.println(s + " --> " + subMap.get(s));
}
System.out.println(" -- myMap (after putting some mappings to subMap) --");
for (String s : myMap.keySet()) {
System.out.println(s + " --> " + myMap.get(s));
}
}
}
Output:
-- subMap --
B --> VB
C --> VC
-- subMap (after putting some mappings to subMap) --
B --> VB
B1 --> VB1
B2 --> VB2
C --> VC
-- myMap (after putting some mappings to subMap) --
A --> VA
B --> VB
B1 --> VB1
B2 --> VB2
C --> VC
D --> VD
E --> VE
8. headMap(K toKey)
SortedMap<K,V> headMap(K toKey)
Trả về chế độ xem của một phần của SortedMap này bao gồm các ánh xạ với khoá nhỏ hơn toKey. (key < toKey).
SortedMap trả về có liên hệ với SortedMap hiện tại, các thay đổi trên SortedMap này có ảnh hưởng tới SortedMap kia và ngược lại.
SortedMap_headMap_ex1.java
package org.o7planning.sortedmap.ex;
import java.util.SortedMap;
import java.util.TreeMap;
public class SortedMap_headMap_ex1 {
public static void main(String[] args) {
SortedMap<String, String> myMap = new TreeMap<>();
myMap.put("A", "VA");
myMap.put("B", "VB");
myMap.put("C", "VC");
myMap.put("D", "VD");
myMap.put("D1", "VD1");
myMap.put("E", "VE");
// A Head Map (elements < "D1")
SortedMap<String, String> headMap = myMap.headMap("D1");
System.out.println(" -- headMap --");
for (String s : headMap.keySet()) {
System.out.println(s + " --> " + headMap.get(s));
}
}
}
Output:
-- headMap --
A --> VA
B --> VB
C --> VC
D --> VD
9. tailMap(K fromKey)
SortedMap<K,V> tailMap(K fromKey)
Trả về chế độ xem của một phần của SortedMap này bao gồm các ánh xạ với khoá lớn hơn hoặc bằng fromKey. (key >= fromKey).
SortedMap trả về có liên hệ với SortedMap hiện tại, các thay đổi trên SortedMap này có ảnh hưởng tới SortedMap kia và ngược lại.
Các hướng dẫn Java Collections Framework
- Hướng dẫn và ví dụ Java PriorityBlockingQueue
- Hướng dẫn sử dụng nền tảng tập hợp trong Java (Java Collection Framework)
- Hướng dẫn và ví dụ Java SortedSet
- Hướng dẫn và ví dụ Java List
- Hướng dẫn và ví dụ Java Iterator
- Hướng dẫn và ví dụ Java NavigableSet
- Hướng dẫn và ví dụ Java ListIterator
- Hướng dẫn và ví dụ Java ArrayList
- Hướng dẫn và ví dụ Java CopyOnWriteArrayList
- Hướng dẫn và ví dụ Java LinkedList
- Hướng dẫn và ví dụ Java Set
- Hướng dẫn và ví dụ Java TreeSet
- Hướng dẫn và ví dụ Java CopyOnWriteArraySet
- Hướng dẫn và ví dụ Java Queue
- Hướng dẫn và ví dụ Java Deque
- Hướng dẫn và ví dụ Java IdentityHashMap
- Hướng dẫn và ví dụ Java WeakHashMap
- Hướng dẫn và ví dụ Java Map
- Hướng dẫn và ví dụ Java SortedMap
- Hướng dẫn và ví dụ Java NavigableMap
- Hướng dẫn và ví dụ Java HashMap
- Hướng dẫn và ví dụ Java TreeMap
- Hướng dẫn và ví dụ Java PriorityQueue
- Hướng dẫn và ví dụ Java BlockingQueue
- Hướng dẫn và ví dụ Java ArrayBlockingQueue
- Hướng dẫn và ví dụ Java TransferQueue
Show More