Tập hợp TreeSet
trong Java là gì?
Lớp TreeSet
trong Java cài đặt (implement) Set Interface, nó sử dụng một cây (tree) cho lưu giữ các phần tử. TreeSet kế thừa lớp (extends) AbstractSet
và cài đặt (implement) NavigableSet Interface
. Các đối tượng của lớp TreeSet
được lưu trữ theo thứ tự tăng dần.
Các điểm quan trọng về lớp TreeSet
trong java là:
- Chỉ chứa các phần tử duy nhất giống như
HashSet
. - Duy trì thứ tự tăng dần.
TreeSet
không cho phép chứa phần tử null.- Bạn cần phải cung cấp bộ Comparator trong khi tạo một
TreeSet
. Nếu bạn không cung cấp bộ so sánh (Comparator) cho TreeSet, các phần tử sẽ được đặt theo thứ tự tăng dần. TreeSet
không được đồng bộ. Để có được một TreeSet đồng bộ, hãy sử dụng phương thức Collections.synchronizedSortedSet ().- Độ phức tạp của
TreeSet
là log(n) cho thao tác thêm (insertion), loại bỏ (removal) và truy xuất (retrieval). TreeSet
sử dụngTreeMap
để lưu trữ các phần tử, giống nhưHashSet
vàLinkedHashSet
sử dụngHashMap
vàLinkedHashMap
tương ứng để lưu trữ các phần tử của chúng.
Khởi tạo TreeSet
trong Java
TreeSet()
: khởi tạo một tập hợp rỗng.TreeSet(Collection c)
: khởi tạo một tập hợp với các phần tử của collection cTreeSet(Comparator comparator)
: khởi tạo một tập hợp rỗng mà các phần tử được xếp thứ tự theo bộ so sánh được xác định bởi comparator.
java
TreeSet<Integer> numbers = new TreeSet<>();
Ở đây, chúng ta đã tạo một TreeSet
mà không có bất kỳ đối số nào. Trong trường hợp này, các phần tử trong TreeSet
được sắp xếp tự nhiên (thứ tự tăng dần).
Tuy nhiên, chúng ta có thể tùy chỉnh việc sắp xếp các phần tử bằng cách sử dụng Comparator interface
. Chúng ta sẽ tìm hiểu về nó ở phần sau trong hướng dẫn này.
Chèn các phần tử vào TreeSet
add()
– chèn phần tử được chỉ định vào tập hợp.addAll()
– chèn tất cả các phần tử của tập hợp được chỉ định vào tập hợp.
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> evenNumbers = new TreeSet<>();
// Using the add() method
evenNumbers.add(2);
evenNumbers.add(4);
evenNumbers.add(6);
System.out.println("TreeSet: " + evenNumbers);
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(1);
// Using the addAll() method
numbers.addAll(evenNumbers);
System.out.println("New TreeSet: " + numbers);
}
}
Kết quả
TreeSet: [2, 4, 6]
New TreeSet: [1, 2, 4, 6]
Duyệt qua các phần tử trong TreeSet
Để truy cập các phần tử của một tập cây, chúng ta có thể sử dụng iterator()
. Để sử dụng phương thức này, chúng ta phải nhập gói java.util.Iterator
.
java
import java.util.TreeSet;
import java.util.Iterator;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Calling iterator() method
Iterator<Integer> iterate = numbers.iterator();
System.out.print("TreeSet using Iterator: ");
// Accessing elements
while(iterate.hasNext()) {
System.out.print(iterate.next());
System.out.print(", ");
}
}
}
Kết quả
TreeSet: [2, 5, 6]
TreeSet using Iterator: 2, 5, 6,
Xóa các phần tử trong TreeSet
remove()
– xóa phần tử được chỉ định khỏi tập hợpremoveAll()
– xóa tất cả các phần tử khỏi tập hợp
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using the remove() method
boolean value1 = numbers.remove(5);
System.out.println("Is 5 removed? " + value1);
// Using the removeAll() method
boolean value2 = numbers.removeAll(numbers);
System.out.println("Are all elements removed? " + value2);
}
}
Kết quả
TreeSet: [2, 5, 6]
Is 5 removed? true
Are all elements removed? true
Phương pháp điều hướng trong TreeSet
Vì lớp TreeSet thực thi NavigableSet, nó cung cấp các phương thức khác nhau để điều hướng qua các phần tử của tập cây.
first()
– trả về phần tử đầu tiên của tập hợplast()
– trả về phần tử cuối cùng của tập hợp
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using the first() method
int first = numbers.first();
System.out.println("First Number: " + first);
// Using the last() method
int last = numbers.last();
System.out.println("Last Number: " + last);
}
}
Kết quả
TreeSet: [2, 5, 6]
First Number: 2
Last Number: 6
higher(element)
- Trả về phần tử thấp nhất trong số các phần tử lớn hơn giá trị được chỉ định element.lower(element)
– Trả về phần tử lớn nhất trong số các phần tử nhỏ hơn giá trị được chỉ định element.ceiling(element)
– Trả về phần tử thấp nhất trong số các phần tử lớn hơn giá trị đã chỉ định thành phần. Nếu element được truyền tồn tại trong một tập hợp cây, nó trả về giá trị element được truyền dưới dạng đối số.floor(element)
– Trả về phần tử lớn nhất trong số các phần tử nhỏ hơn giá trị được chỉ định element. Nếu element được truyền tồn tại trong một tập hợp cây, nó trả về giá trị element được truyền dưới dạng đối số.
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(4);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using higher()
System.out.println("Using higher: " + numbers.higher(4));
// Using lower()
System.out.println("Using lower: " + numbers.lower(4));
// Using ceiling()
System.out.println("Using ceiling: " + numbers.ceiling(4));
// Using floor()
System.out.println("Using floor: " + numbers.floor(3));
}
}
Kết quả
TreeSet: [2, 4, 5, 6]
Using higher: 5
Using lower: 2
Using ceiling: 4
Using floor: 2
pollFirst()
– trả về và xóa phần tử đầu tiên khỏi tập hợppollLast()
– trả về và xóa phần tử cuối cùng khỏi tập hợp
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(4);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using pollFirst()
System.out.println("Removed First Element: " + numbers.pollFirst());
// Using pollLast()
System.out.println("Removed Last Element: " + numbers.pollLast());
System.out.println("New TreeSet: " + numbers);
}
}
Kết quả
TreeSet: [2, 4, 5, 6]
Removed First Element: 2
Removed Last Element: 6
New TreeSet: [4, 5]
headSet(phần tử, booleanValue)
- trả về tất cả các yếu tố của một bộ cây trước khi quy định thành phần (được chuyển như một đối số). Tham số booleanValue là tùy chọn. Giá trị mặc định của nó làfalse
. Nếutrue
được thông qua dưới dạng booleanValue, phương thức trả về tất cả các phần tử trước phần tử được chỉ định bao gồm phần tử được chỉ định.
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(4);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using headSet() with default boolean value
System.out.println("Using headSet without boolean value: " + numbers.headSet(5));
// Using headSet() with specified boolean value
System.out.println("Using headSet with boolean value: " + numbers.headSet(5, true));
}
}
Kết quả
TreeSet: [2, 4, 5, 6]
Using headSet without boolean value: [2, 4]
Using headSet with boolean value: [2, 4, 5]
tailSet(phần tử, booleanValue)
- phương thứctailSet()
trả về tất cả các yếu tố của một bộ cây sau khi quy định thành phần (được truyền dưới dạng tham số) bao gồm thành phần. Tham sốbooleanValue
là tùy chọn. Giá trị mặc định của nó làtrue
. Nếufalse
được thông qua dưới dạngbooleanValue
, phương thức trả về tất cả các phần tử sau thành phần mà không bao gồm các thành phần.
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(4);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using tailSet() with default boolean value
System.out.println("Using tailSet without boolean value: " + numbers.tailSet(4));
// Using tailSet() with specified boolean value
System.out.println("Using tailSet with boolean value: " + numbers.tailSet(4, false));
}
}
Kết quả
TreeSet: [2, 4, 5, 6]
Using tailSet without boolean value: [4, 5, 6]
Using tailSet with boolean value: [5, 6]
subSet(e1, bv1, e2, bv2)
- phương thứcsubSet()
trả về tất cả các yếu tố giữa e1 và e2 kể cả e1. Các bv1 và bv2là các tham số tùy chọn. Giá trị mặc định của bv1 làtrue
, và giá trị mặc định của bv2 làfalse
. Nếufalse
được truyền vào bv1, phương thức trả về tất cả các phần tử giữa e1 và e2 mà không bao gồm e1. Nếutrue
được truyền vào là bv2, phương thức trả về tất cả các phần tử giữa e1 và e2, kể cả e1.
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(2);
numbers.add(5);
numbers.add(4);
numbers.add(6);
System.out.println("TreeSet: " + numbers);
// Using subSet() with default boolean value
System.out.println("Using subSet without boolean value: " + numbers.subSet(4, 6));
// Using subSet() with specified boolean value
System.out.println("Using subSet with boolean value: " + numbers.subSet(4, false, 6, true));
}
}
Kết quả
TreeSet: [2, 4, 5, 6]
Using subSet without boolean value: [4, 5]
Using subSet with boolean value: [5, 6]
Hoạt động của Set
Các phương thức của lớp TreeSet
cũng có thể được sử dụng để thực hiện các hoạt động tập hợp khác nhau.
Liên hiệp các Set
Để thực hiện kết hợp giữa hai tập hợp, chúng ta sử dụng phương thức addAll()
java
import java.util.TreeSet;;
class Main {
public static void main(String[] args) {
TreeSet<Integer> evenNumbers = new TreeSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("TreeSet1: " + evenNumbers);
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
System.out.println("TreeSet2: " + numbers);
// Union of two sets
numbers.addAll(evenNumbers);
System.out.println("Union is: " + numbers);
}
}
Kết quả
TreeSet1: [2, 4]
TreeSet2: [1, 2, 3]
Union is: [1, 2, 3, 4]
Giao điểm của Set
Để thực hiện giao giữa hai tập hợp, ta sử dụng phương thức retainAll()
.
java
import java.util.TreeSet;;
class Main {
public static void main(String[] args) {
TreeSet<Integer> evenNumbers = new TreeSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("TreeSet1: " + evenNumbers);
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
System.out.println("TreeSet2: " + numbers);
// Intersection of two sets
numbers.retainAll(evenNumbers);
System.out.println("Intersection is: " + numbers);
}
}
Kết quả
TreeSet1: [2, 4]
TreeSet2: [1, 2, 3]
Intersection is: [2]
Sự khác biệt của các set
Để tính toán sự khác biệt giữa hai tập hợp, chúng ta có thể sử dụng phương thức removeAll()
java
import java.util.TreeSet;;
class Main {
public static void main(String[] args) {
TreeSet<Integer> evenNumbers = new TreeSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
System.out.println("TreeSet1: " + evenNumbers);
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
System.out.println("TreeSet2: " + numbers);
// Difference between two sets
numbers.removeAll(evenNumbers);
System.out.println("Difference is: " + numbers);
}
}
Kết quả
TreeSet1: [2, 4]
TreeSet2: [1, 2, 3, 4]
Difference is: [1, 3]
Tập hợp con của một Tập hợp
Để kiểm tra một tập hợp có phải là tập hợp con của tập hợp khác hay không, chúng ta sử dụng phương thức containsAll()
java
import java.util.TreeSet;
class Main {
public static void main(String[] args) {
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
System.out.println("TreeSet1: " + numbers);
TreeSet<Integer> primeNumbers = new TreeSet<>();
primeNumbers.add(2);
primeNumbers.add(3);
System.out.println("TreeSet2: " + primeNumbers);
// Check if primeNumbers is subset of numbers
boolean result = numbers.containsAll(primeNumbers);
System.out.println("Is TreeSet2 subset of TreeSet1? " + result);
}
}
Kết quả
TreeSet1: [1, 2, 3, 4]
TreeSet2: [2, 3]
Is TreeSet2 subset of TreeSet1? True
Các phương thức khác của TreeSet
Phương thức | Sự miêu tả |
---|---|
clone() |
Tạo một bản sao của TreeSet |
contains() |
Tìm kiếm TreeSet cho phần tử được chỉ định và trả về kết quả Boolean |
isEmpty() |
Kiểm tra xem TreeSet có trống không |
size() |
Trả về kích thước của TreeSet |
clear() |
Loại bỏ tất cả các phần tử khỏi TreeSet |
So sánh TreeSet
và HashSet
Cả hai TreeSet cũng như HashSet đều triển khai từ Set interface. Tuy nhiên, tồn tại một số khác biệt giữa chúng.
- Không giống như
HashSet
, các phần tử trong TreeSet được lưu trữ theo một số thứ tự. Đó là bởi vìTreeSet
thực hiệnSortedSet
interface là tốt. TreeSet
cung cấp một số phương thức để điều hướng dễ dàng. Ví dụ,first()
,last()
,headSet()
,tailSet()
... Đó là bởi vìTreeSet
cũng thực hiện cácNavigableSet
interface.HashSet
nhanh hơn so TreeSet với các thao tác cơ bản như thêm, bớt, chứa và kích thước.