Java Collections: Quản lý data như Gen Z pro!
Java – OOP

Java Collections: Quản lý data như Gen Z pro!

Author

Admin System

@root

Ngày xuất bản

22 Mar, 2026

Lượt xem

2 Lượt

Collections Framework

Chào các bạn, lại là anh Creyt đây! Hôm nay, chúng ta sẽ "bung lụa" với một chủ đề mà anh dám cá là bạn nào đã và đang "lướt" qua Java đều phải "đụng chạm" tới: Collections Framework. Nghe tên thì có vẻ "hàn lâm" đúng không? Nhưng thực ra, nó chính là "tủ đồ thần kỳ" giúp chúng ta sắp xếp, quản lý mọi thứ trong code một cách "ngon ơ" nhất. Tưởng tượng xem, nếu code của bạn là một bữa tiệc, thì Collections Framework chính là đội ngũ phục vụ chuyên nghiệp, đảm bảo mọi món ăn (dữ liệu) đều được bày biện đúng chỗ, dễ tìm, dễ dùng. Mà Gen Z mình thì thích nhanh gọn, hiệu quả, đúng không nào?

Vậy, Collections Framework là cái gì mà "ghê gớm" vậy? Nói một cách "đời thường", nó là một tập hợp các giao diện (interfaces) và lớp (classes) trong Java, được thiết kế để lưu trữ và thao tác với một nhóm các đối tượng (objects). Thay vì phải tự tay "xây nhà" để chứa từng loại dữ liệu, Java đã "xây sẵn" cho bạn cả một "khu đô thị" với nhiều kiểu nhà khác nhau, mỗi kiểu phục vụ một mục đích riêng.

Nó giống như việc bạn có một "kho đồ" mà trong đó:

  • List (Danh sách): Giống như một cuốn sổ ghi chép các việc cần làm (to-do list) hoặc danh sách nhạc của bạn. Mọi thứ có thứ tự, bạn có thể thêm trùng lặp, và quan trọng là, bạn biết chính xác vị trí của từng món đồ. "Anh ơi, bài số 3 trong playlist là bài gì?" – List trả lời được ngay!
  • Set (Tập hợp): Đây là "hội nhóm" của những người "độc nhất vô nhị". Mỗi thành viên chỉ có mặt một lần duy nhất. Giống như danh sách khách mời VIP không được trùng tên. Bạn không quan tâm thứ tự, chỉ cần biết "người này có trong danh sách hay không?".
  • Map (Bản đồ/Từ điển): Cái này thì "chất" khỏi bàn! Nó giống như một cuốn từ điển hoặc danh bạ điện thoại. Mỗi "tên" (key) sẽ đi kèm với một "số điện thoại" (value) tương ứng. Bạn muốn tìm số của "anh Creyt"? Chỉ cần gõ "Creyt" là ra ngay! Key là duy nhất, nhưng value thì có thể trùng.
  • Queue (Hàng đợi): Giống như hàng người đang xếp hàng mua vé xem concert của idol vậy. Ai đến trước thì được phục vụ trước (First-In, First-Out - FIFO). Hoặc có những loại Queue ưu tiên, ai "VIP" hơn thì được vào trước.

Mục đích chính của nó? Đơn giản là để bạn quản lý "đống data" một cách hiệu quả, dễ dàng thêm, xóa, tìm kiếm mà không phải "đau đầu" nghĩ cách tối ưu từ đầu.

Để các bạn không bị "lú", anh Creyt sẽ "show" ngay vài ví dụ code "sương sương" để các bạn hình dung nhé. Đây là những "công thức nấu ăn" cơ bản nhất để "chế biến" dữ liệu với Collections.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Queue;
import java.util.LinkedList; // LinkedList implements both List and Queue

public class CollectionsDemo {
    public static void main(String[] args) {
        // 1. List: Danh sách có thứ tự, cho phép trùng lặp
        // Ví dụ: Danh sách các tựa game yêu thích
        List<String> gameList = new ArrayList<>();
        gameList.add("Cyberpunk 2077");
        gameList.add("The Witcher 3");
        gameList.add("Elden Ring");
        gameList.add("The Witcher 3"); // Cho phép trùng lặp
        System.out.println("--- Danh sách Game (List) ---");
        System.out.println("Các game hiện có: " + gameList); // In ra cả danh sách
        System.out.println("Game thứ 2 trong danh sách: " + gameList.get(1)); // Lấy theo chỉ mục
        gameList.remove("Cyberpunk 2077"); // Xóa một game
        System.out.println("Danh sách sau khi xóa Cyberpunk: " + gameList);
        System.out.println("-----------------------------\n");

        // 2. Set: Tập hợp không có thứ tự, không cho phép trùng lặp
        // Ví dụ: Danh sách bạn bè trên mạng xã hội (mỗi người chỉ có 1 lần)
        Set<String> friendSet = new HashSet<>();
        friendSet.add("An");
        friendSet.add("Binh");
        friendSet.add("Chau");
        friendSet.add("An"); // Thêm trùng lặp sẽ bị bỏ qua
        System.out.println("--- Danh sách Bạn bè (Set) ---");
        System.out.println("Các bạn bè hiện có: " + friendSet); // Thứ tự có thể không giống lúc thêm
        System.out.println("An có trong danh sách không? " + friendSet.contains("An"));
        friendSet.remove("Binh"); // Xóa một người bạn
        System.out.println("Danh sách sau khi xóa Binh: " + friendSet);
        System.out.println("-----------------------------\n");

        // 3. Map: Lưu trữ dữ liệu dưới dạng cặp Key-Value (Từ điển)
        // Ví dụ: Danh sách điểm của sinh viên (Tên là Key, Điểm là Value)
        Map<String, Double> studentScores = new HashMap<>();
        studentScores.put("Hoang", 8.5);
        studentScores.put("Mai", 9.0);
        studentScores.put("Quang", 7.8);
        studentScores.put("Hoang", 9.2); // Key "Hoang" đã có, value mới sẽ ghi đè value cũ
        System.out.println("--- Điểm Sinh viên (Map) ---");
        System.out.println("Điểm của các sinh viên: " + studentScores);
        System.out.println("Điểm của Mai: " + studentScores.get("Mai")); // Lấy điểm của Mai
        studentScores.remove("Quang"); // Xóa sinh viên Quang
        System.out.println("Điểm sau khi Quang bỏ học: " + studentScores);
        System.out.println("-----------------------------\n");

        // 4. Queue: Hàng đợi (First-In, First-Out)
        // Ví dụ: Hàng đợi xử lý tin nhắn
        Queue<String> messageQueue = new LinkedList<>();
        messageQueue.offer("Tin nhắn từ Sơn"); // Thêm vào cuối hàng đợi
        messageQueue.offer("Tin nhắn từ Thảo");
        messageQueue.offer("Tin nhắn từ Nam");
        System.out.println("--- Hàng đợi Tin nhắn (Queue) ---");
        System.out.println("Hàng đợi hiện tại: " + messageQueue);
        System.out.println("Tin nhắn đầu tiên: " + messageQueue.peek()); // Xem phần tử đầu mà không xóa
        System.out.println("Xử lý tin nhắn: " + messageQueue.poll()); // Lấy và xóa phần tử đầu
        System.out.println("Hàng đợi sau khi xử lý: " + messageQueue);
        System.out.println("-----------------------------\n");
    }
}

Được rồi, "có nghề" rồi thì phải biết vài "chiêu" để code mình "xịn" hơn chứ nhỉ? Anh Creyt có vài mẹo nhỏ mà "có võ" cho các bạn đây:

Illustration

Gợi Ý Đọc Tiếp
Object Class: Ông Trùm Đứng Sau Mọi Object Java

5 Lượt xem

  • Chọn đúng "công cụ" cho việc cần làm: Giống như bạn không thể dùng búa để đóng đinh ốc vậy. Cần danh sách có thứ tự, trùng lặp? Dùng List. Cần tập hợp các đối tượng duy nhất? Dùng Set. Cần lưu trữ theo cặp khóa-giá trị? Dùng Map. Hiểu rõ đặc tính của từng loại sẽ giúp code chạy nhanh hơn và ít lỗi hơn.
  • "Làm việc" với Interface, không phải Class cụ thể: Thay vì khai báo ArrayList<String> myList = new ArrayList<>();, hãy dùng List<String> myList = new ArrayList<>();. Tại sao ư? Vì nó giúp code của bạn linh hoạt hơn, dễ dàng thay đổi implementation sau này (ví dụ từ ArrayList sang LinkedList) mà không phải sửa quá nhiều chỗ. "Chơi" với nguyên tắc, không "chơi" với chi tiết, đó là đẳng cấp!
  • "Đóng gói" cẩn thận với Generics: Luôn luôn dùng List<String>, Set<Integer>, Map<String, Double>... thay vì List, Set, Map trần trụi. Generics giúp Java kiểm tra lỗi kiểu dữ liệu ngay từ lúc bạn viết code (compile-time), tránh được những lỗi "ngớ ngẩn" khi chạy chương trình (runtime). Giống như bạn dán nhãn rõ ràng cho từng hộp đồ vậy, tránh nhầm lẫn.
  • "Bất biến" nếu có thể: Nếu một Collection không cần thay đổi sau khi được tạo, hãy biến nó thành "bất biến" (immutable). Điều này giúp code an toàn hơn, dễ debug hơn, đặc biệt trong môi trường đa luồng. Java 9+ có List.of(), Set.of(), Map.of() để làm điều này.
  • "Dùng Iterator để lướt qua": Khi bạn cần duyệt qua các phần tử trong Collection và có thể muốn xóa một số phần tử trong quá trình duyệt, hãy dùng Iterator. Nó an toàn hơn và tránh được ConcurrentModificationException so với việc dùng vòng lặp for thông thường khi bạn sửa đổi Collection.

Thế Collections Framework này được ứng dụng ở đâu trong "thế giới thực" mà chúng ta đang "cày" hàng ngày? Nhiều lắm luôn!

  • TikTok/Facebook/Instagram: Khi bạn lướt News Feed, danh sách bạn bè, danh sách follow/follower, hay các hashtag thịnh hành – tất cả đều được quản lý bằng các Collection. Danh sách bạn bè có thể là một Set (độc nhất), News Feed là một List các bài viết, và các hashtag có thể là Map (hashtag -> số lượng sử dụng).
  • Shopee/Lazada/Tiki: Giỏ hàng của bạn là một List các sản phẩm (có thể trùng lặp). Danh sách sản phẩm gợi ý, danh sách sản phẩm đã xem gần đây cũng là List. Khi bạn tìm kiếm sản phẩm theo ID, đó là lúc Map phát huy tác dụng.
  • Các game online: Danh sách người chơi trong một trận đấu, kho đồ của nhân vật, bảng xếp hạng – tất cả đều dùng Collections để lưu trữ và quản lý.
  • Ngân hàng số/Ứng dụng thanh toán: Danh sách giao dịch, danh sách khách hàng, thông tin tài khoản – đều được tổ chức bằng Collections để dễ dàng truy xuất và xử lý.
  • Hệ điều hành: Quản lý các tiến trình đang chạy, các tệp tin trong một thư mục, hàng đợi các tác vụ in ấn – đều là những ví dụ điển hình của Collections.

Nói chung, cứ nơi nào cần quản lý một nhóm các "thứ" gì đó (dù là người, đồ vật, hay dữ liệu), thì ở đó có bóng dáng của Collections Framework.

Anh Creyt đã từng "vật lộn" với Collections Framework này từ những ngày đầu "vào nghề", và có vài kinh nghiệm "xương máu" muốn chia sẻ với các bạn:

  • ArrayList vs LinkedList:
    • ArrayList: Giống như một cái giá sách được đóng cố định. Tối ưu khi bạn cần truy cập phần tử theo chỉ mục (như get(index)) rất nhanh, và thêm/xóa ở cuối danh sách. Nhưng nếu bạn cứ thêm/xóa ở giữa, nó sẽ phải "dịch chuyển" cả đống sách, tốn thời gian. Nên dùng khi bạn cần đọc nhiều, sửa ít ở giữa.
    • LinkedList: Giống như một chuỗi các toa tàu, mỗi toa biết toa trước và toa sau nó là ai. Thêm/xóa ở đầu hoặc giữa rất nhanh vì chỉ cần "cắt nối" vài toa. Nhưng để tìm đến toa thứ N thì phải đi từ đầu, nên get(index) sẽ chậm hơn. Nên dùng khi bạn cần thêm/xóa nhiều ở đầu/giữa danh sách (ví dụ: hàng đợi, stack).
  • HashSet vs TreeSet:
    • HashSet: "Hội nhóm" tự do, không theo thứ tự. Tối ưu cho việc kiểm tra xem một phần tử có tồn tại hay không (contains()) và thêm/xóa rất nhanh. Tuy nhiên, nó không đảm bảo thứ tự các phần tử.
    • TreeSet: "Hội nhóm" có tổ chức, các phần tử được sắp xếp theo một thứ tự tự nhiên hoặc do bạn định nghĩa. Việc thêm/xóa/tìm kiếm cũng khá nhanh, nhưng chậm hơn HashSet một chút vì phải duy trì thứ tự. Nên dùng khi bạn cần các phần tử duy nhất VÀ được sắp xếp.
  • HashMap vs TreeMap:
    • HashMap: "Từ điển" siêu nhanh, không quan tâm thứ tự các từ. Tối ưu cho việc tìm kiếm, thêm, xóa theo key cực kỳ nhanh. Đây là "ngôi sao" được dùng nhiều nhất.
    • TreeMap: "Từ điển" có sắp xếp các từ khóa theo thứ tự. Tối ưu khi bạn cần các cặp key-value được sắp xếp theo key, ví dụ bạn muốn duyệt qua danh sách sản phẩm theo tên theo thứ tự alphabet.

Lời khuyên từ anh Creyt: Hầu hết các trường hợp, bạn sẽ bắt đầu với ArrayList cho ListHashMap cho Map vì chúng cung cấp hiệu năng tốt cho các tác vụ phổ biến. Chỉ khi bạn gặp phải vấn đề về hiệu năng hoặc cần các đặc tính cụ thể (như thứ tự, thêm/xóa ở giữa), bạn mới nên cân nhắc các implementation khác.

Đó, vậy là chúng ta đã "phá đảo" xong Collections Framework rồi đấy! Nhớ nhé, nó không chỉ là một đống class khô khan mà là những "công cụ siêu phàm" giúp bạn "làm chủ" dữ liệu trong Java. Cứ thực hành nhiều, "code dạo" nhiều là sẽ "thấm" ngay thôi. Chúc các bạn "code vui vẻ" và hẹn gặp lại trong những buổi "bung lụa" tiếp theo!

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!