Java TreeSet
TreeSet 是一个元素有序的,可导航搜索的 Set 集合。在本教程中,我们将通过示例学习 Java TreeSet 类以及 TreeSet 的用法。
在本教程中,我们将通过示例学习 Java TreeSet 类以及 TreeSet 的用法。
TreeSet
是一个元素有序的,可导航搜索的 Set 集合。TreeSet
内部使用 TreeMap
作为底层实现,TreeSet
的元素都保存在 TreeMap
的键上。
TreeSet
实现了 NavigableSet
接口。
创建 TreeSet
我们导入 java.util.TreeSet
类后,就可以通过构造方法创建 TreeSet
对象了。例如:
TreeSet<Integer> numbers = new TreeSet<>();
在这里,我们使用默认的 TreeSet
构造函数创建了一个 TreeSet
对象。在这种情况下,TreeSet
中的元素自然排序(升序)。
我们也可以在构造方法中传入 Comparator
比较器对象来自定义元素的排序。我们将在本教程的后面部分介绍它。
TreeSet 的方法
HashSet
完全实现了 NavigableSet
接口以及更上级接口定义的所有的集合操作方法。
将元素插入到 TreeSet
add()
- 将指定的元素添加到 TreeSet 集合中addAll()
- 将指定集合的所有元素添加到 TreeSet 集合中
例如,
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
TreeSet<Integer> evenNumbers = new TreeSet<>();
evenNumbers.add(2);
evenNumbers.add(4);
evenNumbers.add(6);
System.out.println("TreeSet: " + evenNumbers);
TreeSet<Integer> numbers = new TreeSet<>();
numbers.add(1);
numbers.addAll(evenNumbers);
System.out.println("New TreeSet: " + numbers);
}
}
输出
TreeSet: [2, 4, 6]
New TreeSet: [1, 2, 4, 6]
TreeSet 迭代器
iterator()
返回一个迭代器,可以迭代当前 TreeSet
对象中的元素。
import java.util.TreeSet;
import java.util.Iterator;
public 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);
Iterator<Integer> iterate = numbers.iterator();
System.out.print("TreeSet using Iterator: ");
while (iterate.hasNext()) {
System.out.print(iterate.next());
System.out.print(", ");
}
}
}
输出
TreeSet: [2, 5, 6]
TreeSet using Iterator: 2, 5, 6,
关于迭代器的更多信息,请转到 Java 迭代器章节查看。
删除元素
remove()
- 从 TreeSet 集合中删除指定的元素removeAll()
- 从 TreeSet 集合中删除由参数指定的另一个集合的所有元素
例如,
import java.util.TreeSet;
public 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);
boolean value1 = numbers.remove(5);
System.out.println("Is 5 removed? " + value1);
boolean value2 = numbers.removeAll(numbers);
System.out.println("Are all elements removed? " + value2);
}
}
输出
TreeSet: [2, 5, 6]
Is 5 removed? true
Are all elements removed? true
导航方法
TreeSet
该类实现了 NavigableSet
接口,它实现了 NavigableSet
接口定义的用于导航搜索元素的方法。
first() 和 last() 方法
first()
- 返回集合的第一个元素last()
- 返回集合的最后一个元素
例如,
import java.util.TreeSet;
public 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);
int first = numbers.first();
System.out.println("First Number: " + first);
int last = numbers.last();
System.out.println("Last Number: " + last);
}
}
输出
TreeSet: [2, 5, 6]
First Number: 2
Last Number: 6
搜索最接近的元素的方法
higher(e)
- 返回那些大于指定的元素中的最小的元素。lower(e)
- 返回那些小于指定的元素中的最大的元素。ceiling(e)
- 返回那些大于或等于指定的元素中的最小的元素。floor(e)
- 返回那些小于或等于指定的元素中的最大的元素。
例如,
import java.util.TreeSet;
public 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);
System.out.println("Using higher(4): " + numbers.higher(4));
System.out.println("Using lower(4): " + numbers.lower(4));
System.out.println("Using ceiling(4): " + numbers.ceiling(4));
System.out.println("Using floor(3): " + numbers.floor(3));
}
}
输出
TreeSet: [2, 4, 5, 6]
Using higher(4): 5
Using lower(4): 2
Using ceiling(4): 4
Using floor(3): 2
pollfirst() 和 pollLast() 方法
pollFirst()
- 删除并返回集合中的第一个元素pollLast()
- 删除并返回集合中的最后一个元素
例如,
import java.util.TreeSet;
public 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);
System.out.println("Removed First Element: " + numbers.pollFirst());
System.out.println("Removed Last Element: " + numbers.pollLast());
System.out.println("New TreeSet: " + numbers);
}
}
输出
TreeSet: [2, 4, 5, 6]
Removed First Element: 2
Removed Last Element: 6
New TreeSet: [4, 5]
headSet(toElement, inclusive);
headSet(toElement, inclusive)
方法返回由 toElement
元素之前的所有元素组成的 TreeSet
集合。
inclusive
参数如果为 false
,该方法返回的集合中不包括指定元素;如果为 true
,该方法返回的集合中包括指定元素。
例如,
import java.util.TreeSet;
public 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);
System.out.println("Using headSet without boolean value: " + numbers.headSet(5));
System.out.println("Using headSet with boolean value: " + numbers.headSet(5, true));
}
}
输出
TreeSet: [2, 4, 5, 6]
Using headSet without boolean value: [2, 4]
Using headSet with boolean value: [2, 4, 5]
tailSet(fromElement, inclusive)
tailSet(fromElement, inclusive)
方法返回由 fromElement
元素之后的所有元素组成的 TreeSet
集合。
inclusive
参数如果为 false
,该方法返回的集合中不包括指定元素;如果为 true
,该方法返回的集合中包括指定元素。
例如,
import java.util.TreeSet;
public 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);
System.out.println("Using tailSet without boolean value: " + numbers.tailSet(4));
System.out.println("Using tailSet with boolean value: " + numbers.tailSet(4, false));
}
}
输出
TreeSet: [2, 4, 5, 6]
Using tailSet without boolean value: [4, 5, 6]
Using tailSet with boolean value: [5, 6]
subSet(fromElement, fromInclusive, toElement, toInclusive)
subSet(fromElement, fromInclusive, toElement, toInclusive)
方法返回 fromElement
元素和 toElement
元素之间的所有元素组成的 TreeSet
集合。
如果 fromInclusive
为 true
,则返回的集合中包括 fromElement
元素, 为 false
则不包括 fromElement
元素。
如果 toInclusive
为 true
,则返回的集合中包括 toElement
元素, 为 false
则不包括 toElement
元素。
例如,
import java.util.TreeSet;
public 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);
System.out.println("Using subSet without boolean value: " + numbers.subSet(4, 6));
System.out.println("Using subSet with boolean value: " + numbers.subSet(4, false, 6, true));
}
}
输出
TreeSet: [2, 4, 5, 6]
Using subSet without boolean value: [4, 5]
Using subSet with boolean value: [5, 6]
集合操作
TreeSet
类的方法还可用于执行各种集合操作。
集合的并集
要计算两个集合之间的并集,我们可以使用 addAll()
方法。例如,
import java.util.TreeSet;
;
public 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);
numbers.addAll(evenNumbers);
System.out.println("Union is: " + numbers);
}
}
输出
TreeSet1: [2, 4]
TreeSet2: [1, 2, 3]
Union is: [1, 2, 3, 4]
集合的交集
要计算两个集合之间的交集,我们可以使用 retainAll()
方法。例如
import java.util.TreeSet;
;
public 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);
numbers.retainAll(evenNumbers);
System.out.println("Intersection is: " + numbers);
}
}
输出
TreeSet1: [2, 4]
TreeSet2: [1, 2, 3]
Intersection is: [2]
集合的差集
要计算两个集合之间的差集异,我们可以使用 removeAll()
方法。例如,
import java.util.TreeSet;
;
public 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);
numbers.removeAll(evenNumbers);
System.out.println("Difference is: " + numbers);
}
}
输出
TreeSet1: [2, 4]
TreeSet2: [1, 2, 3, 4]
Difference is: [1, 3]
集合的子集
要检查一个集合是否是另一个集合的子集,我们可以使用 containsAll()
方法。例如,
import java.util.TreeSet;
public 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);
boolean result = numbers.containsAll(primeNumbers);
System.out.println("Is TreeSet2 subset of TreeSet1? " + result);
}
}
输出
TreeSet1: [1, 2, 3, 4]
TreeSet2: [2, 3]
Is TreeSet2 subset of TreeSet1? true
TreeSet 的其他方法
clone()
- 克隆一个HashSet
contains()
- 如果HashSet
包含指定元素,则返回true
isEmpty()
- 检查HashSet
是否为空size()
- 返回HashSet
大小clear()
- 清空HashSet
TreeSet 比较器
在上面的所有示例中, TreeSet 元素都是自然排序的。但是,我们也可以自定义元素的顺序。
我们可以根据自己的需求创建我们自定义的比较器类。例如,
import java.util.TreeSet;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
// Creating a tree set with customized comparator
TreeSet<String> animals = new TreeSet<>(new CustomComparator());
animals.add("Dog");
animals.add("Zebra");
animals.add("Cat");
animals.add("Horse");
System.out.println("TreeSet: " + animals);
}
// Creating a comparator class
public static class CustomComparator implements Comparator<String> {
@Override
public int compare(String animal1, String animal2) {
return animal1.compareTo(animal2) * -1;
}
}
}
输出
TreeSet: [Zebra, Horse, Dog, Cat]
在上面的例子中,我们创建 TreeSet 对象时,在构造方法中使用自定义比较器对象作为参数。
关于自定义比较器的说明:
- 自定义比较器需要实现
Comparator
接口 compare(a, b)
方法需要传入每次参与比较的 2 个参数,返回值需满足下列条件:- 如果
a > b
返回大于0
的整数 - 如果
a < b
返回小于0
的整数 - 如果
a = b
返回0
- 如果
然后我们重写了 compare()
方法以相反的顺序对元素进行排序。
TreeSet 与 HashSet
TreeSet
和 HashSet
都实现了 Set
接口。但它们之间存在一些差异:
- 与
HashSet
不同,TreeSet
中的元素以某种顺序存储。这是因为TreeSet
实现了SortedSet
接口。 TreeSet
提供了一些用于导航搜索的方法。例如,first()
,last()
,headSet(
),tailSet()
等,这是因为TreeSet
也实现了NavigableSet
接口。HashSet
比TreeSet
速度快。
请转到 Java HashSet 章节了解更多信息。