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ính Mô 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ặp Mỗ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óng Set 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. HashSet | Lư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. LinkedHashSet | Triể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. TreeSet | Lư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ính | Mô Tả |
|---|---|
| 1. Triển Khai Bằng Bảng Băm | HashSet đượ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ặp | HashSet 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ảo | Thứ 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ính | Mô Tả |
|---|---|
| 1. Chỉ Chứa Phần Tử Duy Nhất | LinkedHashSet chỉ chứa các phần tử duy nhất, giống như HashSet. |
| 2. Cho Phép Phần Tử Null | LinkedHashSet cho phép phần tử null. |
| 3. Duy Trì Thứ Tự Chèn | LinkedHashSet 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èn | LinkedHashSet 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èn | LinkedHashSet 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ệt | LinkedHashSet 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ầu | Mô tả |
|---|---|
| Sắp xếp các phần tử theo thứ tự tự nhiên của chúng | Sắ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ặp | Mỗ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ếp | TreeSet 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ên | Nế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 nhau | Nế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ếp | TreeSet 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:
Phương Thức Mô 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 phần tử trùng lặp: [1, 3, 5, 8, 9]
TreeSet sau khi xóa phần tử 8: [1, 3, 5, 9]
Phần tử nhỏ nhất trong TreeSet: 1
Phần tử lớn nhất trong TreeSet: 9
Phần tử lớn hơn hoặc bằng 5: 5Như 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
| HashSet | LinkedHashSet | TreeSet | |
|---|---|---|---|
| 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ử Null | Cho 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