TreeMap: Sắp xếp dữ liệu như dân chuyên, không lo lộn xộn!
Java – OOP

TreeMap: Sắp xếp dữ liệu như dân chuyên, không lo lộn xộn!

Author

Admin System

@root

Ngày xuất bản

22 Mar, 2026

Lượt xem

3 Lượt

TreeMap class

Chào mấy đứa, anh Creyt đây! Hôm nay chúng ta sẽ đào sâu vào một "siêu phẩm" trong bộ sưu tập Collections của Java, đó là TreeMap. Nghe cái tên có vẻ học thuật nhưng thật ra nó "cool" hơn mấy đứa tưởng nhiều.

TreeMap là gì mà "hot" vậy anh Creyt?

Để dễ hình dung, mấy đứa cứ nghĩ thế này: Nếu HashMap giống như cái tủ lạnh nhà mình, mấy đứa cứ ném đồ ăn vào đại khái rồi tự nhớ xem socola ở ngăn nào, sữa chua ở đâu (nhanh gọn nhưng đôi khi hơi lộn xộn nếu không nhớ kỹ). Thì TreeMap lại giống như cái kệ sách trong thư viện hoặc một playlist nhạc được sắp xếp cẩn thận theo vần ABC, hoặc theo thời gian phát hành. Lúc nào cần tìm cuốn sách hay bài hát nào đó, chỉ cần nhìn vào thứ tự là thấy ngay, không cần phải lục tung lên.

Nói một cách "code-er" hơn: TreeMap là một lớp triển khai giao diện Map trong Java, nhưng nó có một điểm đặc biệt: nó tự động sắp xếp các cặp khóa-giá trị (key-value pairs) theo thứ tự tự nhiên của khóa (natural order) hoặc theo một Comparator mà mấy đứa định nghĩa. Nghĩa là, khi mấy đứa thêm dữ liệu vào, TreeMap sẽ lo luôn phần sắp xếp, và khi mấy đứa duyệt qua nó, dữ liệu sẽ luôn nằm trong một trật tự nhất định.

Để làm gì?

TreeMap sinh ra để giải quyết bài toán khi mấy đứa cần một tập hợp các cặp khóa-giá trị có thứ tự. Ví dụ: muốn hiển thị danh sách sản phẩm theo tên từ A-Z, hay danh sách người dùng theo điểm số từ cao xuống thấp, hoặc các sự kiện theo thời gian diễn ra. TreeMap làm điều này một cách "automatic" và hiệu quả.

Illustration

Code Ví Dụ Minh Hoạ: "Sổ Tay" TreeMap của Creyt

Giờ thì, bắt tay vào code để thấy nó hoạt động như thế nào nhé. Anh sẽ dùng một ví dụ đơn giản về việc lưu trữ các từ vựng và nghĩa của chúng, được sắp xếp theo thứ tự bảng chữ cái.

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

public class TreeMapDemo {

    public static void main(String[] args) {
        // 1. Khởi tạo một TreeMap cơ bản: Khóa là String, Giá trị là String
        // TreeMap sẽ tự động sắp xếp các khóa theo thứ tự bảng chữ cái (natural order)
        System.out.println("\n--- Ví dụ 1: TreeMap với thứ tự tự nhiên của khóa (String) ---");
        TreeMap<String, String> dictionary = new TreeMap<>();

        // 2. Thêm các cặp khóa-giá trị vào TreeMap
        dictionary.put("Apple", "Táo");
        dictionary.put("Banana", "Chuối");
        dictionary.put("Cat", "Mèo");
        dictionary.put("Dog", "Chó");
        dictionary.put("Ant", "Kiến"); // Thêm 'Ant' vào sau nhưng nó vẫn sẽ được sắp xếp lên đầu

        System.out.println("Từ điển sau khi thêm các từ:");
        // 3. Duyệt và in ra các phần tử (sẽ thấy chúng đã được sắp xếp)
        for (Map.Entry<String, String> entry : dictionary.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

        // 4. Lấy giá trị theo khóa
        System.out.println("\nNghĩa của từ 'Banana': " + dictionary.get("Banana"));

        // 5. Kiểm tra sự tồn tại của khóa
        System.out.println("Có từ 'Cat' trong từ điển không? " + dictionary.containsKey("Cat"));
        System.out.println("Có từ 'Zebra' trong từ điển không? " + dictionary.containsKey("Zebra"));

        // 6. Xóa một phần tử
        dictionary.remove("Dog");
        System.out.println("\nTừ điển sau khi xóa 'Dog':");
        for (Map.Entry<String, String> entry : dictionary.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

        // 7. Ví dụ với khóa là số nguyên, sắp xếp giảm dần bằng Comparator
        System.out.println("\n--- Ví dụ 2: TreeMap với Comparator tùy chỉnh (sắp xếp giảm dần) ---");
        // Khởi tạo TreeMap với một Comparator để sắp xếp khóa Integer theo thứ tự giảm dần
        TreeMap<Integer, String> scores = new TreeMap<>(Comparator.reverseOrder());

        scores.put(100, "Alice");
        scores.put(85, "Bob");
        scores.put(92, "Charlie");
        scores.put(105, "David"); // David có điểm cao nhất, sẽ đứng đầu

        System.out.println("Bảng điểm (sắp xếp giảm dần):");
        for (Map.Entry<Integer, String> entry : scores.entrySet()) {
            System.out.println("Điểm: " + entry.getKey() + ", Tên: " + entry.getValue());
        }

        // Một số phương thức hữu ích khác của TreeMap
        System.out.println("\n--- Một số phương thức hữu ích khác ---");
        System.out.println("Khóa đầu tiên (nhỏ nhất): " + dictionary.firstKey());
        System.out.println("Khóa cuối cùng (lớn nhất): " + dictionary.lastKey());
        System.out.println("Cặp khóa-giá trị đầu tiên: " + dictionary.firstEntry());
        System.out.println("Cặp khóa-giá trị cuối cùng: " + dictionary.lastEntry());

        // subMap: lấy một phần của map trong khoảng khóa nhất định
        Map<String, String> subDict = dictionary.subMap("B", true, "C", true); // Từ 'B' đến 'C' (bao gồm cả 'B' và 'C')
        System.out.println("\nSub-dictionary từ 'B' đến 'C':");
        for (Map.Entry<String, String> entry : subDict.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

Mẹo Vặt & Best Practices từ anh Creyt (để không bị "ngáo ngơ")

  1. Khi nào thì dùng TreeMap? Nghe nè mấy đứa! Chỉ dùng TreeMap khi mấy đứa thực sự cần dữ liệu được sắp xếp theo khóa. Nếu không cần sắp xếp, HashMap sẽ nhanh hơn nhiều vì nó không phải tốn công sức để duy trì thứ tự. TreeMap có chi phí hiệu năng cao hơn một chút (các thao tác put, get, remove đều có độ phức tạp là O(log n), trong khi HashMap trung bình là O(1)).
  2. Khóa phải "sắp xếp được": Các khóa trong TreeMap phải là các đối tượng có khả năng so sánh được. Tức là chúng phải triển khai giao diện Comparable (như String, Integer, Double mặc định đã có) hoặc mấy đứa phải cung cấp một Comparator khi khởi tạo TreeMap (như ví dụ scores ở trên).
  3. Cẩn thận với null: TreeMap không cho phép khóa null nếu không có Comparator tùy chỉnh. Nếu có Comparator, nó sẽ phụ thuộc vào cách Comparator xử lý null.
  4. subMap, headMap, tailMap: Đây là những phương thức cực kỳ mạnh mẽ của TreeMap! Chúng cho phép mấy đứa lấy ra một "phần" của map mà không cần phải duyệt toàn bộ. Rất hữu ích khi làm việc với dữ liệu có khoảng thời gian, khoảng giá trị cụ thể. Cứ tưởng tượng mấy đứa có một cuốn từ điển khổng lồ, và chỉ muốn xem các từ bắt đầu từ 'M' đến 'P', subMap chính là cái filter thần thánh đó!

Ứng dụng Thực Tế: "À há! Ra là nó dùng ở đây!"

  • Leaderboards/Bảng xếp hạng: Trong các game online hoặc ứng dụng thể thao, TreeMap có thể được dùng để lưu trữ điểm số của người chơi và tự động sắp xếp họ từ cao xuống thấp. Khóa là điểm số (hoặc kết hợp điểm số và ID người chơi), giá trị là thông tin người chơi.
  • Hệ thống đặt lịch/Thời gian biểu: Lưu trữ các sự kiện theo thời gian. Khóa là LocalDateTime hoặc Date, giá trị là chi tiết sự kiện. Khi duyệt, các sự kiện sẽ hiện ra theo đúng trình tự thời gian.
  • Từ điển/Glossary: Như ví dụ code của anh, TreeMap là lựa chọn tuyệt vời để xây dựng một từ điển, nơi các từ khóa (từ) được sắp xếp theo bảng chữ cái.
  • Cấu hình hệ thống: Trong một số trường hợp, các file cấu hình cần được đọc và xử lý theo một thứ tự nhất định, TreeMap có thể giúp duy trì thứ tự đó.
  • Các hệ thống caching có thời gian sống (TTL): Lưu trữ các mục cache với thời gian hết hạn làm khóa, giúp dễ dàng tìm và loại bỏ các mục đã hết hạn.

Thử Nghiệm & Nên Dùng Cho Case Nào?

Anh Creyt đã từng "đau đầu" với việc phải sắp xếp thủ công một danh sách các Object dựa trên nhiều tiêu chí khác nhau. Lúc đó, anh thử dùng ArrayList rồi Collections.sort(), nhưng mỗi lần thêm sửa là lại phải sắp xếp lại, rất tốn kém. Cho đến khi TreeMap xuất hiện như một vị cứu tinh!

Nên dùng TreeMap khi:

  • Thứ tự quan trọng: Mấy đứa cần dữ liệu luôn được sắp xếp theo khóa khi duyệt hoặc truy xuất.
  • Truy xuất theo khoảng: Cần tìm các phần tử trong một khoảng khóa nhất định (dùng subMap, headMap, tailMap).
  • Tìm kiếm min/max: Cần nhanh chóng tìm khóa nhỏ nhất (firstKey()) hoặc lớn nhất (lastKey()).

Không nên dùng TreeMap khi:

  • Không cần sắp xếp: Nếu chỉ cần lưu trữ và truy xuất nhanh mà không quan tâm thứ tự, HashMap sẽ hiệu quả hơn về mặt hiệu năng.
  • Hiệu năng là ưu tiên số 1 tuyệt đối và dữ liệu lớn: Dù O(log n) là tốt, nhưng với dữ liệu cực lớn và tần suất thao tác cực cao, sự khác biệt giữa O(1) của HashMap và O(log n) của TreeMap có thể đáng kể.

Nhớ nhé, chọn đúng công cụ cho đúng việc là kỹ năng quan trọng nhất của một developer xịn sò. TreeMap là một công cụ mạnh mẽ, nhưng hãy dùng nó một cách thông minh!

Chúc mấy đứa code vui vẻ và hiểu bài! Hẹn gặp lại trong bài học tiếp theo của anh Creyt!

Thuộc Series: Java – OOP

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!