Thứ Hai, 15 tháng 4, 2024

Set

 


A. Set Interface

Set interface đại diện cho một tập hợp không có thứ tự các phần tử và không chứa các phần tử trùng lặp, bao gồm HashSet, TreeSet và LinkedHashSet ( TreeSet thường được sử dụng. )

Một số điểm chính về Set interface:

    • Điểm ChínhMô Tả
      1. Không Có Thứ Tự Cụ ThểCác phần tử trong một Set không có thứ tự cụ thể. Điều này có nghĩa là không thể truy cập các phần tử bằng chỉ mục như trong một List.
      2. Không Chứa Phần Tử Trùng LặpMỗi phần tử chỉ xuất hiện một lần trong một Set. Khi thêm một phần tử đã tồn tại vào Set, phần tử đó sẽ bị bỏ qua và Set vẫn giữ nguyên.
      3. Cung Cấp Các Thao Tác Nhanh ChóngSet cung cấp các phương thức để kiểm tra sự tồn tại của một phần tử (như contains()) và thêm/xóa phần tử một cách nhanh chóng (như add() và remove())

Cấu Trúc Dữ LiệuĐặc Điểm
1. HashSetLưu trữ các phần tử trong bảng băm, cách thực hiện tốt nhất. Không đảm bảo về thứ tự của các phần tử.
2. LinkedHashSetTriển khai dưới dạng bảng băm với cấu trúc dữ liệu danh sách liên kết. Sắp xếp các phần tử theo thứ tự chúng được chèn vào tập hợp.
3. TreeSetLưu trữ các phần tử trong một cây và sắp xếp chúng dựa trên các giá trị của phần tử. Chậm hơn HashSet.
B. HashSet


Điểm ChínhMô Tả
1. Triển Khai Bằng Bảng BămHashSet được triển khai bằng cách sử dụng bảng băm dựa trên HashMap. Mỗi phần tử trong HashSet là một khóa trong HashMap, với giá trị tương ứng là một đối tượng Object, giá trị của mỗi khóa trong HashMap là null.
2. Không Chứa Phần Tử Trùng LặpHashSet không chứa các phần tử trùng lặp. Mỗi phần tử chỉ xuất hiện một lần trong HashSet.
3. Thứ Tự Không Được Đảm BảoThứ tự của các phần tử trong HashSet không được đảm bảo. Các phần tử có thể được sắp xếp theo bất kỳ thứ tự nào.
4. Không Đồng BộHashSet không đồng bộ, điều này có nghĩa là nó không an toàn cho các hoạt động đồng thời từ nhiều luồng (threads).

C. LinkedHashSet

Điểm ChínhMô Tả
1. Chỉ Chứa Phần Tử Duy NhấtLinkedHashSet chỉ chứa các phần tử duy nhất, giống như HashSet.
2. Cho Phép Phần Tử NullLinkedHashSet cho phép phần tử null.
3. Duy Trì Thứ Tự ChènLinkedHashSet duy trì thứ tự chèn của các phần tử. Điều này có nghĩa là thứ tự mà các phần tử được thêm vào sẽ được duy trì khi duyệt qua tập hợp.
4. Không Đồng BộLinkedHashSet không đồng bộ, có nghĩa là nó không an toàn cho các hoạt động đồng thời từ nhiều luồng (threads).
5. Sử Dụng Bảng Băm và Duy Trì Thứ Tự ChènLinkedHashSet sử dụng cấu trúc dữ liệu bảng băm như HashSet, nhưng mỗi mục trong bảng băm được kết nối với mục trước đó và mục tiếp theo để duy trì thứ tự chèn.
6. Thích Hợp Khi Cần Duy Trì Thứ Tự ChènLinkedHashSet thường được sử dụng khi bạn cần duy trì thứ tự chèn của các phần tử trong tập hợp của mình.
7. Lựa Chọn Phổ Biến cho Việc Lưu Trữ và DuyệtLinkedHashSet cung cấp tất cả các tính năng của HashSet với sự bổ sung của việc duy trì thứ tự chèn, làm cho nó trở thành một lựa chọn phổ biến cho việc lưu trữ và duyệt qua dữ liệu theo thứ tự chèn.

D. TreeSet

Yêu cầuMô tả
Sắp xếp các phần tử theo thứ tự tự nhiên của chúngSắp xếp các phần tử theo thứ tự mà chúng tự nhiên xuất hiện, ví dụ: số nguyên sẽ được sắp xếp tăng dần, chuỗi sẽ được sắp xếp theo thứ tự từ điển.
Không chứa các phần tử trùng lặpMỗi phần tử trong tập hợp phải là duy nhất, không được phép có các phần tử trùng lặp.
Không đồng bộTreeSet không đồng bộ, điều này có nghĩa là nó không được đảm bảo rằng các thao tác truy cập và sửa đổi được an toàn khi có nhiều luồng thực thi cùng lúc.
Sử dụng giao diện Comparable hoặc Comparator để sắp xếpTreeSet sử dụng giao diện Comparable hoặc Comparator để xác định thứ tự của các phần tử. Nếu không cung cấp, TreeSet sẽ sử dụng thứ tự tự nhiên của các phần tử (nếu có).
Nếu các phần tử được sắp xếp tự nhiênNếu các phần tử có thể được sắp xếp tự nhiên (ví dụ: số nguyên, chuỗi), không cần phải cung cấp bất kỳ phương thức so sánh nào.
Nếu bạn muốn sắp xếp các phần tử theo một cách khác nhauNếu muốn sắp xếp các phần tử theo một cách khác nhau (ví dụ: sắp xếp chuỗi theo độ dài), bạn có thể cung cấp một đối tượng Comparator.
TreeSet là một cấu trúc dữ liệu mạnh mẽ và linh hoạt trong Java để duy trì một tập hợp các phần tử theo thứ tự được sắp xếpTreeSet là một cấu trúc dữ liệu trong Java để lưu trữ tập hợp các phần tử không trùng lặp theo thứ tự được sắp xếp. Nó cung cấp các phương thức hiệu quả để thực hiện các thao tác tập hợp.

Dưới đây là một số phương thức quan trọng của TreeSet trong Java:

  1. Phương ThứcMô Tả
    1. Thêm và Loại Bỏ Phần Tử
    add(E e)Thêm một phần tử vào TreeSet nếu chưa tồn tại. Trả về true nếu thêm thành công, false nếu đã tồn tại.
    addAll(Collection<? extends E> c)Thêm tất cả các phần tử từ một collection khác vào TreeSet.
    remove(Object o)Loại bỏ một phần tử khỏi TreeSet nếu tồn tại trong tập hợp.
    pollFirst()Loại bỏ và trả về phần tử nhỏ nhất trong TreeSet.
    pollLast()Loại bỏ và trả về phần tử lớn nhất trong TreeSet.
    clear()Loại bỏ tất cả các phần tử trong TreeSet, làm cho TreeSet trở thành trống rỗng.
    2. Truy Vấn và Kiểm Tra
    contains(Object o)Kiểm tra xem một phần tử có tồn tại trong TreeSet hay không.
    isEmpty()Kiểm tra xem TreeSet có rỗng không.
    size()Trả về số lượng phần tử trong TreeSet.
    3. Truy Xuất Phần Tử
    ceiling(E e)Trả về phần tử nhỏ nhất lớn hơn hoặc bằng phần tử được chỉ định.
    floor(E e)Trả về phần tử lớn nhất nhỏ hơn hoặc bằng phần tử được chỉ định.
    first()Trả về phần tử nhỏ nhất trong TreeSet.
    last()Trả về phần tử lớn nhất trong TreeSet.
    subSet(E fromElement, E toElement)Trả về một tập hợp con chứa các phần tử từ phần tử lớn hơn hoặc bằng fromElement đến phần tử nhỏ hơn toElement.
    headSet(E toElement)Trả về một tập hợp con chứa các phần tử nhỏ hơn toElement.
    tailSet(E fromElement)Trả về một tập hợp con chứa các phần tử lớn hơn hoặc bằng fromElement.

Dưới đây là một ví dụ minh họa về cách sử dụng TreeSet để lưu trữ và sắp xếp các phần tử duy nhất theo thứ tự tăng dần:

import java.util.*; public class TreeSetExample { public static void main(String[] args) { // Khởi tạo một TreeSet TreeSet<Integer> treeSet = new TreeSet<>(); // Thêm các phần tử vào TreeSet treeSet.add(5); treeSet.add(3); treeSet.add(8); treeSet.add(1); treeSet.add(9); // In ra TreeSet System.out.println("TreeSet ban đầu: " + treeSet); // Thêm một phần tử đã tồn tại treeSet.add(3); // TreeSet sẽ tự loại bỏ các phần tử trùng lặp System.out.println("TreeSet sau khi thêm phần tử trùng lặp: " + treeSet); // Xóa một phần tử treeSet.remove(8); // In ra TreeSet sau khi xóa phần tử System.out.println("TreeSet sau khi xóa phần tử 8: " + treeSet); // Lấy phần tử nhỏ nhất System.out.println("Phần tử nhỏ nhất trong TreeSet: " + treeSet.first()); // Lấy phần tử lớn nhất System.out.println("Phần tử lớn nhất trong TreeSet: " + treeSet.last()); // Lấy phần tử lớn hơn hoặc bằng 5 (nếu không có, trả về null) System.out.println("Phần tử lớn hơn hoặc bằng 5: " + treeSet.ceiling(5)); } }

Kết quả khi chạy chương trình:

TreeSet ban đầu: [1, 3, 5, 8, 9] TreeSet sau khi thêm phn ttrùng lp: [1, 3, 5, 8, 9] TreeSet sau khi xóa phn t8: [1, 3, 5, 9] Phn tnhnht trong TreeSet: 1 Phn tln nht trong TreeSet: 9 Phn tln hơn hoc bng 5: 5

Như bạn có thể thấy, TreeSet tự động sắp xếp các phần tử theo thứ tự tăng dần và loại bỏ các phần tử trùng lặp khi được thêm vào.

E. So sánh HashSet, LinkedHashSet và TreeSet


HashSetLinkedHashSetTreeSet
Cách thức làm việc?Sử dụng HashMap nội bộ để lưu trữ các phần tử.Sử dụng LinkedHashMap nội bộ để lưu trữ các phần tử.Sử dụng TreeMap nội bộ để lưu trữ các phần tử.
Thứ tự của các phần tử (Order Of Elements)Không duy trì bất kỳ thứ tự các phần tử được thêm vào.Duy trì thứ tự chèn của các phần tử. Các phần tử được lưu trữ đúng như thứ tự chúng được chèn vào.Duy trì thứ tự các phần tử theo bộ so sánh được cung cấp (Comparator). Nếu không có bộ so sánh được cung cấp, các phần tử sẽ được đặt theo thứ tự tăng dần tự nhiên của chúng.
Hiệu suất (Performance)Cho hiệu suất tốt hơn so với LinkedHashSet và TreeSet.Nằm giữa HashSet và TreeSet. Hiệu suất của nó hầu như tương tự như HashSet. Nhưng hơi chậm hơn vì nó cũng duy trì LinkedList nội bộ để duy trì trình tự chèn các phần tử.Cho hiệu suất thấp hơn HashSet và LinkedHashSet vì nó phải sắp xếp các phần tử sau mỗi lần chèn và loại bỏ.
Thao tác thêm, xóa và truy xuất phần tửCho hiệu suất của lệnh O(1) để chèn, loại bỏ và truy xuất phần tử.Cũng cho hiệu suất của lệnh O(1) để chèn, loại bỏ và truy xuất phần tử.Cho hiệu suất của lệnh O(log (n)) cho các thao tác chèn, loại bỏ và truy xuất phần tử.
So sánh các phần tửSử dụng các phương thức equals() và hashCode() để so sánh các phần tử và do đó loại bỏ các phần tử có thể trùng lặp.Cũng sử dụng phương thức equals() và hashCode() để so sánh các phần tử.Sử dụng phương pháp compare() hoặc compareTo() để so sánh các phần tử và do đó loại bỏ các phần tử có thể trùng lặp. Nó không sử dụng các phương thức equals() và hashCode() để so sánh các phần tử.
Phần tử NullCho phép tối đa một phần tử null.Cũng cho phép tối đa một phần tử null.Không cho phép chứa phần tử null. Nếu bạn cố gắng để chèn null thành phần TreeSet, nó ném NullPointerException.
Sử dụng bộ nhớĐòi hỏi ít bộ nhớ hơn LinkedHashSet và TreeSet vì nó chỉ sử dụng HashMap nội bộ để lưu trữ các phần tử của nó.Yêu cầu bộ nhớ nhiều hơn HashSet vì nó cũng duy trì LinkedList cùng với HashMap để lưu trữ các phần tử của nó.Cũng yêu cầu bộ nhớ nhiều hơn HashSet vì nó cũng duy trì bộ so sánh để sắp xếp các phần tử cùng với TreeMap.
Khi nào sử dụng?Nếu bạn muốn danh sách không chứa phần tử trùng và không cần duy trì bất kỳ thứ tự các phần tử được chèn vào.Nếu bạn muốn danh sách không chứa phần tử trùng và muốn duy trì thứ tự chèn của các phần tử.Nếu bạn muốn danh sách không chứa phần tử trùng và muốn sắp xếp các phần tử theo một số so sánh.

Không có nhận xét nào:

Đăng nhận xét