1. TreeMap trong Java là gì?

TreeMap trong Java là một lớp được xây dựng dựa theo cấu trúc dữ liệu cây đỏ-đen, nó được sử dụng để lưu trữ các phần tử theo dạng cặp giá trị KeyValue. TreeMap được sử dụng khi bạn cần lưu trữ các phần tử theo một thứ tự, bởi vì lớp này là lớp có thể duy trì thứ tự tăng dần.

Lớp TreeMap là lớp triển khai của Interface NavigableMap và lớp TreeMap kế thừa lại từ lớp AbstractMap. Trong hình trên, ta có thể thấy Interface NavigableMap kế thừa SortedMapSortedMap kế thừa Map. Vì thế mà TreeMap có khá nhiều tính chất tương tự như các lớp cha của nó. Các tính chất của lớp TreeMap mà ta cần phải biết:

  • TreeMap chỉ cho phép lưu trữ các phần tử có khóa Key là duy nhất
  • TreeMap không cho phép lưu trữ các khóa Key với giá trị là Null, tuy nhiên lại có thể lưu trữ nhiều các Value mang giá trị Null.
  • TreeMap không được đồng bộ hóa.
  • TreeMap có duy trì thứ tự tăng dần.

Lớp TreeMap được tìm thấy trong gói java.util. vì vậy để sử dụng được lớp này, ta cần nhập vào thư viện import java.util.*;

2. Khai báo TreeMap trong Java

Lớp TreeMap trong Java lữu trữ các phần tử là các cặp giá trị KeyValue, khi khai báo (khởi tạo) một đối tượng cho lớp TreeMap ta cần chỉ rõ ra kiểu dữ liệu cho Key và chỉ ra kiểu dữ liệu cho Value của các phần tử được lưu trữ trong TreeMap. Cú pháp khai báo lớp TreeMap() trong Java như sau:

TreeMap <typeKey, typeValue> name = new TreeMap <typeKey, typeValue>();

Trong đó:

  • typeKey là kiểu dữ liệu của khóa trong TreeMap
  • typeValue là kiểu dữ liệu của giá trị tương ứng với khóa trong TreeMap
  • name là tên của đối tượng TreeMap cần khởi tạo

Lớp TreeMap() sẽ gồm 4 constructor. Dưới đây là bảng liệt kê các constructor của lớp này và mô tả các cách sử dụng các constructor đó:

Constructor Mô tả
TreeMap() Constructor mặc định của lớp TreeMap. Nó sẽ tạo ra một TreeMap trống và được sắp xếp tăng dần các phần tử.
TreeMap(Comparator<? super K> comparator) Khởi tạo một TreeMap được sắp xếp bằng cách sử dụng trình so sánh so sánh Comparator.
TreeMap(Map<? extends K,? extends V> m) Khởi tạo một TreeMap với các phần tử được nhập từ một Map. Được sắp xếp theo thứ tự tăng dần các phần tử.
TreeMap(SortedMap<K,? extends V> m) Khởi tạo một TreeMap với các phần tử được nạp từ một SortedMap. Được sắp xếp theo thứ tự thứ tự phần tử của SortedMap.

Dưới đây sẽ là ví dụ về câu lệnh khởi tạo một TreeMap trong Java. Tiếp theo, khi việc khởi tạo TreeMap thành công chúng ta sẽ cùng nhau kiểm tra xem TreeMap đó có rỗng không? Sau đó hiển thị ra toàn bộ phần tử có trong TreeMap như sau:

import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();    
        //Kiem tra TreeMap vua tao co rong hay khong?
        boolean result = treeMap.isEmpty();
        System.out.println("TreeMap vua khoi tao co rong hay khong? \n" + result);
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMap la: \n" + treeMap);    
    }  
}
TreeMap vua khoi tao co rong hay khong? 
true
Phan tu co trong TreeMap la: 
{}

Nhận xét: TreeMap mới khi được khởi tạo sẽ không có phần tử nào nên sẽ là một TreeMap rỗng. Ngoài ra các phần tử của TreeMap được lưu trữ trong dấu ngoặc nhọn {} – điều này khá tương đồng với HashMapMap.

3. Thao tác với TreeMap trong Java

Các thao tác phổ biến khi làm việc với TreeMap đó là: Thêm phần tử vào TreeMap, duyệt các phần tử trong TreeMap, xóa phần tử trong TreeMap, trích xuất phần tử trong TreeMapMời các bạn cùng xem các ví dụ dưới đây để hiểu rõ hơn cách thức thực hiện các thao tác trên với TreeMap!

3.1 Thêm phần tử vào TreeMap trong Java

Mỗi phần tử thuộc TreeMap sẽ là các cặp giá trị Key, Value. Thế nên, để thực hiện việc thêm phần tử vào trong một TreeMap ta cần thêm đầy đủ cả KeyValue. TreeMap sẽ không cho phép lưu trữ các Key bằng Null và chúng cũng không cho phép lưu trữ các Key là trùng lặp.

Để thực hiện thêm phần tử vào trong TreeMap, ta cần gọi đến phương thức put() – phương thức này sẽ nhận vào hai giá trị là Key Value của một phần tử cần thêm vào TreeMap. Cùng xem ví dụ dưới đây để hiểu rõ hơn về phương thức này!

import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();    
        //Kiem tra TreeMap vua tao co rong hay khong?
        boolean result = treeMap.isEmpty();
        System.out.println("TreeMap vua khoi tao co rong hay khong? \n" + result);
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMap ban dau la: \n" + treeMap);  
        
        //Them phan tu vao TreeMap
       	treeMap.put(100,"Nam");    
        treeMap.put(102,"Ha");    
        treeMap.put(101,"Thanh");    
        treeMap.put(103,"Son"); 
        
        //Kiem tra TreeMap sau khi them phan tu co rong hay khong?
        boolean result2 = treeMap.isEmpty();
        System.out.println("TreeMap sau khi them phan tu co rong hay khong? \n" + result2);
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMapla: \n" + treeMap);  
    }  
}

Kết quả:

TreeMap vua khoi tao co rong hay khong? 
true
Phan tu co trong TreeMap ban dau la: 
{}
TreeMap sau khi them phan tu co rong hay khong? 
false
Phan tu co trong TreeMapla: 
{100=Nam, 101=Thanh, 102=Ha, 103=Son}

TreeMap có tính duy trì thứ tự nên khi thêm phần tử thành công, nó sẽ sắp xếp các phần tử đó theo thứ tự tăng dần dựa vào Key của phần tử.

3.2 Duyệt các phần tử trong TreeMap

Thao tác duyệt các phần tử trong TreeMap ta cần sử dụng đến Map.Entry – chúng sẽ trả về một Set mới với các phần tử trong nó sẽ thuộc trong TreeMap và việc duyệt các phần tử trong TreeMap lúc này sẽ chuyển thành duyệt các phần tử trong Set.

Trong quá trình duyệt các phần tử trong TreeMap ta cũng có thể lấy Key của phần tử đang được duyệt thông qua phương thức getKey() và có thể lấy Value của phần tử đang được duyệt thông qua phương thức getValues().

import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();   
        
        //Them phan tu vao TreeMap
       	treeMap.put(100,"Nam");    
        treeMap.put(102,"Ha");    
        treeMap.put(101,"Thanh");    
        treeMap.put(103,"Son"); 
       
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMapla: \n" + treeMap); 
        
        //Duyet phan tu thong qua Map.Entry
        for(Map.Entry m : treeMap.entrySet()){    
            //Hien thi cac gia tri Key:Value
            System.out.println(m.getKey()+":"+m.getValue());    
        }    
    }  
}

Kết quả:

Phan tu co trong TreeMapla: 
{100=Nam, 101=Thanh, 102=Ha, 103=Son}
100:Nam
101:Thanh
102:Ha
103:Son

3.3 Trích xuất phần tử trong TreeMap

Như đã đề cập ở trên, TreeMap duy trì tính chất các phần tử được sắp xếp theo thứ tự (mặc định là tăng dần theo Key) nên khi làm việc với chúng, ta sẽ hoàn toàn có thể lấy ra một số lượng phần tử nhất định có trong TreeMap. Có rất nhiều các trích xuất phần tử trong TreeMap được đề cập ở bên dưới đây:

  • Lấy ra các phần tử nằm trong khoảng từ đầu TreeMap đến phần tử có Key được chỉ định trong phương thức headMap()
import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();   
        
        //Them phan tu vao TreeMap
       	treeMap.put(100,"Nam");    
        treeMap.put(102,"Ha");    
        treeMap.put(101,"Thanh");    
        treeMap.put(103,"Son"); 
       
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMapla: \n" + treeMap); 
        //Phan tu tu dau TreeMap den phan tu co Key duoc chi dinh
        System.out.println("Lay ra phan tu dau den phan tu co Key duoc chi dinh \n" + treeMap.headMap (101,true)); 
    }  
}

Kết quả:

Phan tu co trong TreeMapla: 
{100=Nam, 101=Thanh, 102=Ha, 103=Son}
Lay ra phan tu dau den phan tu co Key duoc chi dinh 
{100=Nam, 101=Thanh}
  • Lấy ra phần tử nằm trong khoảng từ Key được chỉ định trong phương thức tailMap() đến hết các phần tử trong TreeMap 
import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();   
        
        //Them phan tu vao TreeMap
       	treeMap.put(100,"Nam");    
        treeMap.put(102,"Ha");    
        treeMap.put(101,"Thanh");    
        treeMap.put(103,"Son"); 
       
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMapla: \n" + treeMap); 
        //Phan tu bat dau tu Key = 101 den het TreeMap
        System.out.println("Lay ra phan tu bat dau tu Key = 101 den het TreeMap \n" + treeMap.tailMap(101,true)); 
    }  
}
  • Lấy ra các phần tử nằm trong khoảng từ Key bắt đầu đến Key kết thúc được chỉ định trong phương thức subMap()
import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();   
        
        //Them phan tu vao TreeMap
       	treeMap.put(100,"Nam");    
        treeMap.put(102,"Ha");    
        treeMap.put(101,"Thanh");    
        treeMap.put(103,"Son"); 
       
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMapla: \n" + treeMap); 
        //Lay ra cac phan tu bat dau tu Key=100 ket thuc o Key = 102
        System.out.println("Cac phan tu trong khoang bat dau tu Key=100 va ket thuc Key=102 \n" + treeMap.subMap(100,true,102,true)); 
    }  
}

Kết quả:

Phan tu co trong TreeMapla: 
{100=Nam, 101=Thanh, 102=Ha, 103=Son}
Cac phan tu trong khoang bat dau tu Key=100 va ket thuc Key=102 
{100=Nam, 101=Thanh, 102=Ha}

3.4 Xóa phần tử trong TreeMap

Việc xóa phần tử trong TreeMap sẽ loại bỏ đi cặp giá trị KeyValue của phần tử đó. Sau khi xóa phần tử có trong TreeMap thì các phần tử còn lại bên trong TreeMap cũng sẽ vẫn duy trì thứ tự (mặc định là tăng dần theo Key).

Để thực hiện thao tác xóa đi một phần tử có trong TreeMap ta cần phải có được Key của phần tử cần xóa khỏi TreeMap, sau đó sẽ sử dụng đến phương thức remove() – phương thức này nhận vào tham số là Key của phần tử cần xóa khỏi TreeMap.

import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();   
        
        //Them phan tu vao TreeMap
       	treeMap.put(100,"Nam");    
        treeMap.put(102,"Ha");    
        treeMap.put(101,"Thanh");    
        treeMap.put(103,"Son"); 
       
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMapla: \n" + treeMap); 
        //Xoa phan tu co Key = 101 va Key = 103
        treeMap.remove(101);     
        treeMap.remove(103);
        //Kiem tra phan tu trong TreeMap sau khi xoa
        System.out.println("TreeMap sau khi xoa phan tu la: \n" + treeMap); 
    }  
}

Kết quả:

Phan tu co trong TreeMapla: 
{100=Nam, 101=Thanh, 102=Ha, 103=Son}
TreeMap sau khi xoa phan tu la: 
{100=Nam, 102=Ha}

Trong trường hợp bạn đang cần xóa đi tất cả các phần tử có trong TreeMap, khi đó bạn chỉ cần gọi đến phương thức clear() để thực hiện việc này! Dưới đây là ví dụ xóa toàn bộ phần tử có trong TreeMap.

import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao lop TreeMap() co Key kieu Integer, Value kieu String
    	TreeMap<Integer,String> treeMap = new TreeMap<Integer,String>();   
        
        //Them phan tu vao TreeMap
       	treeMap.put(100,"Nam");    
        treeMap.put(102,"Ha");    
        treeMap.put(101,"Thanh");    
        treeMap.put(103,"Son"); 
       
        //Kiem tra phan tu trong TreeMap
        System.out.println("Phan tu co trong TreeMapla: \n" + treeMap); 
        //Xoa phan tu toan bo phan tu trong TreeMap
        treeMap.clear();     
        //Kiem tra phan tu trong TreeMap sau khi xoa
        System.out.println("TreeMap sau khi xoa phan tu la: \n" + treeMap); 
    }  
}

Kết quả:

Phan tu co trong TreeMapla: 
{100=Nam, 101=Thanh, 102=Ha, 103=Son}
TreeMap sau khi xoa phan tu la: 
{}

4. Các phương thức của TreeMap trong Java

Lớp TreeMap có khá nhiều các phương thức giống HashMapMap, tuy nhiên trong lớp TreeMap còn bổ xung thêm nhiều các phương thức khác. Trong các ví dụ trên, chúng tôi đã liệt kê ra một vài phương thức phổ biến khi làm việc với TreeMap như: put(), tailMap(), headMap(), subMap(), remove()….để đầy đủ và chi tiết hơn, mời các bạn xem bảng các phương thức của lớp TreeMap ở bên dưới đây!

Phương thức Mô tả
put(Object key, Object value) Chèn một cặp phần tử (Key,Value) vào trong TreeMap.
void putAll(Map map) Chèn các phần tử của TreeMap này vào trong một TreeMap khác.
putIfAbsent(K key, V value) Chèn Value được chỉ định với Key được chỉ định vào trong TreeMap nếu nó chưa có trong TreeMap.
remove(Object key) Xóa đi một cặp phần tử trong TreeMap dựa vào Key
boolean remove(Object key, Object value) Xóa đi một cặp phần tử trong TreeMap dựa theo Key và Value.
Set keySet() Chuyển các Key của TreeMap vào trong một Set.
Set<Map.Entry<K,V>> entrySet() Chuyển đổi các phần tử trong TreeMap sang Set bao gồm giá trị Key,Value của TreeMap ban đầu.
void clear() Xóa đi toàn bộ phần tử trong TreeMap.
boolean equals(Object o) So sánh xem một giá trị được chỉ định với TreeMap xem chúng có bằng nhau không?
boolean containsKey(Object key) Trả về True nếu một Key thuộc trong TreeMap, ngược lại sẽ trả về False.
void forEach(BiConsumer<? super K,? super V> action) Duyệt qua từng phần tử có trong một TreeMap, sau khi tất cả phần tử đã được duyệt xong thì sẽ ném ra một ngoại lệ.
get(Object key) Lấy ra giá trị Value dựa theo Key được chỉ định trong TreeMap.
getOrDefault(Object key, V defaultValue) Lấy ra giá trị Value dựa theo Key. Nếu Key không tồn tại trong TreeMap thì sẽ đặt defaultValue cho Key đó.
int hashCode() Trả về giá trị mã băm cho TreeMap.
boolean isEmpty() Kiểm tra xem TreeMap đó có rỗng hay không?
replace(K key, V value) Thay thế một Value mới dựa theo Key trong TreeMap.
boolean replace(K key, V oldValue, V newValue) Thay thế Value cũ oldValue thành một Value mới newValue dựa vào Key trong TreeMap.
Collection values() Chuyển đổi các Value trong TreeMap vào Collection.
int size() Lấy ra số lượng phần tử trong TreeMap.
descendingMap() Sắp xếp các Key và Value trong TreeMap theo thứ tự giảm dần.
headMap(K toKey) Trả về một khoảng các phần tử từ đầu TreeMap đến phần tử có khóa nhỏ hơn hoặc bằng toKey.
tailMap(K startKey) Trả về một khoảng các phần tử bắt đầu từ startKey đến hết TreeMap.
Object firstKey() Trả về key đầu tiên của TreeMap đã được sắp xếp.
Object lastKey() Trả về key cuối cùng của TreeMap đã được sắp xếp.
subMap((K startKey, K endKey) Trả về một khoảng các phần tử của TreeMap bắt đầu từ phần tử có key startKey đến phần tử có key endKey.