openplanning

Hướng dẫn và ví dụ Java SortedMap

Xem thêm các chuyên mục:

Hãy theo dõi chúng tôi trên Fanpage để nhận được thông báo mỗi khi có bài viết mới. Facebook

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>
Sau đây là so sánh giữa MapSortedMap:
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).
  • TODO Link?
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)key2.equals(key1) phải trả về cùng một giá trị.
  • TODO Link?

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.

5- firstKey()


K firstKey()
Trả về khóa đầu tiên (nhỏ nhất) hiện có trong SortedMap này.

6- lastKey()


K lastKey()
Trả về khóa cuối cùng (lớn nhất) hiện có trong SortedMap này.

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 fromKeytoKey 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.

Xem thêm các chuyên mục: