Skip to main content

Command Palette

Search for a command to run...

Bài 3: Set Interface và Các Implementations

Published
5 min readView as Markdown

I. Giới Thiệu Về Set Interface

Set là một interface trong Java Collection Framework đại diện cho một tập hợp các phần tử không trùng lặp. Không giống như List, Set không duy trì thứ tự chèn phần tử. Set được sử dụng khi cần lưu trữ các phần tử duy nhất và tránh trùng lặp.

II. Các Phương Thức Chính Trong Set Interface

  1. boolean add(E e)

    • Thêm phần tử e vào Set nếu nó không tồn tại trong Set. Trả về true nếu phần tử được thêm vào, ngược lại trả về false.

    • Ví dụ:

        Set<String> set = new HashSet<>();
        boolean isAdded = set.add("A");
        System.out.println(isAdded); // Output: true
        isAdded = set.add("A");
        System.out.println(isAdded); // Output: false
      
  2. boolean contains(Object o)

    • Kiểm tra xem Set có chứa phần tử o hay không. Trả về true nếu Set chứa phần tử, ngược lại trả về false.

    • Ví dụ:

        Set<String> set = new HashSet<>();
        set.add("A");
        boolean contains = set.contains("A");
        System.out.println(contains); // Output: true
        contains = set.contains("B");
        System.out.println(contains); // Output: false
      
  3. boolean remove(Object o)

    • Xóa phần tử o khỏi Set nếu nó tồn tại. Trả về true nếu phần tử bị xóa, ngược lại trả về false.

    • Ví dụ:

        Set<String> set = new HashSet<>();
        set.add("A");
        boolean isRemoved = set.remove("A");
        System.out.println(isRemoved); // Output: true
        isRemoved = set.remove("B");
        System.out.println(isRemoved); // Output: false
      
  4. int size()

    • Trả về số lượng phần tử trong Set.

    • Ví dụ:

        Set<String> set = new HashSet<>();
        set.add("A");
        set.add("B");
        int size = set.size();
        System.out.println(size); // Output: 2
      
  5. void clear()

    • Xóa tất cả các phần tử trong Set.

    • Ví dụ:

        Set<String> set = new HashSet<>();
        set.add("A");
        set.add("B");
        set.clear();
        System.out.println(set.size()); // Output: 0
      

III. Các Lớp Triển Khai Set Interface

  1. HashSet

    • Đặc điểm:

      • Dựa trên bảng băm (hash table).

      • Không duy trì thứ tự các phần tử.

      • Hiệu suất tốt cho các thao tác thêm, xóa, và tìm kiếm phần tử (O(1)).

    • Khi nào sử dụng: Khi cần một tập hợp không trùng lặp và không quan tâm đến thứ tự phần tử.

    • Ví dụ:

        Set<String> hashSet = new HashSet<>();
        hashSet.add("A");
        hashSet.add("B");
        hashSet.add("A"); // Không thêm phần tử trùng lặp
        System.out.println(hashSet); // Output: [A, B]
      
  2. LinkedHashSet

    • Đặc điểm:

      • Kế thừa từ HashSet và sử dụng danh sách liên kết kép để duy trì thứ tự chèn.

      • Hiệu suất tương tự như HashSet nhưng có thêm chi phí để duy trì thứ tự (O(1)).

    • Khi nào sử dụng: Khi cần một tập hợp không trùng lặp nhưng duy trì thứ tự chèn.

    • Ví dụ:

        Set<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("A");
        linkedHashSet.add("B");
        linkedHashSet.add("A"); // Không thêm phần tử trùng lặp
        System.out.println(linkedHashSet); // Output: [A, B]
      
  3. TreeSet

    • Đặc điểm:

      • Dựa trên cây nhị phân tìm kiếm (Red-Black tree).

      • Duy trì thứ tự các phần tử theo thứ tự tự nhiên hoặc theo bộ so sánh (comparator) tùy chỉnh.

      • Hiệu suất cho các thao tác thêm, xóa, và tìm kiếm là O(log n).

    • Khi nào sử dụng: Khi cần một tập hợp không trùng lặp và duy trì thứ tự sắp xếp.

    • Ví dụ:

        Set<String> treeSet = new TreeSet<>();
        treeSet.add("B");
        treeSet.add("A");
        treeSet.add("C");
        System.out.println(treeSet); // Output: [A, B, C]
      
  4. EnumSet

    • Đặc điểm:

      • Tối ưu hóa cho các tập hợp enum.

      • Hiệu suất rất cao cho các thao tác thêm, xóa, và tìm kiếm (O(1)).

      • Chỉ hoạt động với các phần tử kiểu enum.

    • Khi nào sử dụng: Khi cần một tập hợp các giá trị enum.

    • Ví dụ:

        enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
        Set<Day> enumSet = EnumSet.of(Day.MONDAY, Day.WEDNESDAY, Day.FRIDAY);
        System.out.println(enumSet); // Output: [MONDAY, WEDNESDAY, FRIDAY]
      
  5. CopyOnWriteArraySet

    • Đặc điểm:

      • Dựa trên CopyOnWriteArrayList, hỗ trợ đa luồng.

      • Hiệu suất tốt khi đọc nhiều hơn ghi.

      • Mỗi khi có thay đổi (thêm/xóa), danh sách sẽ được sao chép.

    • Khi nào sử dụng: Khi cần một tập hợp đồng bộ mà chủ yếu là thao tác đọc trong môi trường đa luồng.

    • Ví dụ:

        Set<String> cowArraySet = new CopyOnWriteArraySet<>();
        cowArraySet.add("A");
        cowArraySet.add("B");
        cowArraySet.add("A"); // Không thêm phần tử trùng lặp
        System.out.println(cowArraySet); // Output: [A, B]
      

IV. So Sánh Hiệu Năng Và Trường Hợp Sử Dụng

LớpThứ Tự Phần TửHiệu Suất Thêm/XóaHiệu Suất Tìm KiếmĐồng BộKhi Nào Sử Dụng
HashSetKhôngRất nhanh (O(1))Rất nhanh (O(1))KhôngKhi không cần thứ tự
LinkedHashSetTheo thứ tự chènNhanh (O(1))Nhanh (O(1))KhôngKhi cần duy trì thứ tự chèn
TreeSetTheo thứ tự sắp xếpTrung bình (O(log n))Trung bình (O(log n))KhôngKhi cần sắp xếp phần tử
EnumSetTheo thứ tự định nghĩa enumRất nhanh (O(1))Rất nhanh (O(1))KhôngKhi làm việc với enum
CopyOnWriteArraySetTheo thứ tự chènChậm khi ghiNhanh khi đọcKhi cần đồng bộ và đọc nhiều hơn ghi

V. Kết Luận

Trong bài viết này, chúng ta đã khám phá Set interface và các lớp triển khai của nó. Hiểu rõ sự khác nhau và đặc điểm của từng loại Set sẽ giúp bạn chọn lựa cấu trúc dữ liệu phù hợp cho các tình huống cụ thể trong ứng dụng của mình.

VI. Tài Liệu Tham Khảo

  • Java SE Documentation: Java Collections Framework

  • "Effective Java" by Joshua Bloch: Các nguyên tắc và best practices khi sử dụng Collection Framework.

Bài Tập Thực Hành

  1. Tạo một chương trình Java sử dụng HashSet để lưu trữ các từ duy nhất trong một đoạn văn và in ra danh sách các từ này.

  2. Tạo một chương trình Java sử dụng LinkedHashSet để lưu trữ và in ra danh sách các phần tử theo thứ tự chèn.

  3. Tạo một chương trình Java sử dụng TreeSet để lưu trữ và sắp xếp các số nguyên, sau đó in ra danh sách các số này theo thứ tự tăng dần.

  4. Tạo một chương trình Java sử dụng EnumSet để lưu trữ các ngày trong tuần và in ra danh sách các ngày này.

  5. Tạo một chương trình Java sử dụng CopyOnWriteArraySet để lưu trữ các yêu cầu HTTP trong một server

More from this blog

devngu

169 posts