编辑这个页面须要登录或更高权限!
在本教程中,我们将借助示例学习Java TreeSet类及其各种操作和方法。
Java集合框架的TreeSet类提供树数据结构的功能。
它扩展了NavigableSet接口。
为了创建树集,我们必须首先导入java.util.TreeSet包。
导入包之后,下面是如何在Java中创建TreeSet。
TreeSet<Integer> numbers = new TreeSet<>();
在这里,我们创建了一个没有任何参数的TreeSet。在本示例中,TreeSet中的元素自然排序(升序)。
但是,我们可以使用Comparator接口自定义元素的排序。 我们将在本教程的后面部分中学习它。
TreeSet类提供了各种方法,允许我们对集合执行各种操作。
add() - 将指定的元素插入集合
addAll() - 将指定集合的所有元素插入集合
例如,
import java.util.TreeSet; class Main { public static void main(String[] args) { TreeSet<Integer> evenNumbers = new TreeSet<>(); // 使用 the add() 方法 evenNumbers.add(2); evenNumbers.add(4); evenNumbers.add(6); System.out.println("TreeSet: " + evenNumbers); TreeSet<Integer> numbers = new TreeSet<>(); numbers.add(1); // 使用 the addAll() 方法 numbers.addAll(evenNumbers); System.out.println("新的TreeSet: " + numbers); } }
输出结果
TreeSet: [2, 4, 6] 新的TreeSet: [1, 2, 4, 6]
要访问树集的元素,我们可以使用iterator()方法。为了使用这种方法,我们必须导入java.util.Iterator包。例如,
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); // 调用 iterator() 方法 Iterator<Integer> iterate = numbers.iterator(); System.out.print("TreeSet使用迭代器: "); //访问元素 while(iterate.hasNext()) { System.out.print(iterate.next()); System.out.print(", "); } } }
输出结果
TreeSet: [2, 5, 6] TreeSet使用迭代器: 2, 5, 6,
remove() - 从集合中删除指定的元素
removeAll() - 从集合中删除所有元素
例如,
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); // 使用remove() 方法 boolean value1 = numbers.remove(5); System.out.println("5被删除了? " + value1); // 使用removeAll() 方法 boolean value2 = numbers.removeAll(numbers); System.out.println("是否删除了所有元素? " + value2); } }
输出结果
TreeSet: [2, 5, 6] 5被删除了? true 是否删除了所有元素? true
因为TreeSet类实现了NavigableSet,所以它提供了各种方法来导航树集的元素。
first() - 返回集合的第一个元素
last() - 返回集合的最后一个元素
例如,
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); // 使用 first() 方法 int first = numbers.first(); System.out.println("第一个数字: " + first); // 使用 last() 方法 int last = numbers.last(); System.out.println("最后一个数字: " + last); } }
输出结果
TreeSet: [2, 5, 6] 第一个数字: 2 最后一个数字: 6
Higher(element) - 返回大于指定元素(element)的最小元素。
lower(element) - 返回小于指定元素(element)的最大元素。
ceiling(element) - 返回大于指定元素(element)的那些元素中的最小元素。如果传递的元素(element)存在于树集中,则返回作为参数传递的元素(element)。
floor(element) - 返回小于指定元素(element)的元素中最大的元素。如果传递的元素(element)存在于树集中,则返回作为参数传递的元素(element)。
例如,
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); // 使用 higher() System.out.println("使用 higher: " + numbers.higher(4)); // 使用 lower() System.out.println("使用 lower: " + numbers.lower(4)); // 使用 ceiling() System.out.println("使用 ceiling: " + numbers.ceiling(4)); // 使用 floor() System.out.println("使用 floor: " + numbers.floor(3)); } }
输出结果
TreeSet: [2, 4, 5, 6] 使用 higher: 5 使用 lower: 2 使用 ceiling: 4 使用 floor: 2
pollFirst() - 返回并从集合中删除第一个元素
pollLast() - 返回并从集合中删除最后一个元素
例如,
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); // 使用 pollFirst() System.out.println("删除第一个元素: " + numbers.pollFirst()); // 使用 pollLast() System.out.println("删除最后一个元素: " + numbers.pollLast()); System.out.println("新的TreeSet: " + numbers); } }
输出结果
TreeSet: [2, 4, 5, 6] 删除第一个元素: 2 删除最后一个元素: 6 新的TreeSet: [4, 5]
headSet()方法返回指定元素(作为参数传递)之前的树集的所有元素。
booleanValue参数是可选的。默认值为false。
如果booleanValue的值为true,则该方法返回指定元素之前的所有元素,包括指定元素。
例如,
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); // 使用 headSet()使用默认的布尔值 System.out.println("使用不带布尔值的headSet: " + numbers.headSet(5)); // 使用 headSet()使用指定的布尔值 System.out.println("将headSet与布尔值一起使用: " + numbers.headSet(5, true)); } }
输出结果
TreeSet: [2, 4, 5, 6] 使用不带布尔值的headSet: [2, 4] 将headSet与布尔值一起使用: [2, 4, 5]
tailSet()方法返回包含指定元素的指定元素(作为参数传递)之后的树集的所有元素。
booleanValue参数是可选的。默认值为true。
如果false作为a传递booleanValue,则该方法将返回指定后的所有元素,element而不包括指定的element。
例如,
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); // 使用 tailSet()使用默认的布尔值 System.out.println("tailSet()使用默认的布尔值: " + numbers.tailSet(4)); // 使用 tailSet() with specified boolean value System.out.println("tailSet()带有布尔值: " + numbers.tailSet(4, false)); } }
输出结果
TreeSet: [2, 4, 5, 6] 使用 tailSet()使用默认的布尔值: [4, 5, 6] tailSet()带有布尔值: [5, 6]
subSet()方法返回e1和e2之间的所有元素,包括e1。
bv1和bv2是可选参数。 bv1的默认值为true,bv2的默认值为false。
如果将false作为bv1传递,则该方法返回e1和e2之间的所有元素,而不包括e1。
如果将true作为bv2传递,则该方法返回e1和e2之间的所有元素,包括e1。
例如,
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); // 使用 subSet() with default boolean value System.out.println("subSet()使用默认布尔值: " + numbers.subSet(4, 6)); // 使用 subSet() 使用指定的布尔值 System.out.println("subSet()使用指定的布尔值: " + numbers.subSet(4, false, 6, true)); } }
输出结果
TreeSet: [2, 4, 5, 6] subSet()使用默认布尔值: [4, 5] subSet()使用指定的布尔值: [5, 6]
TreeSet类的方法还可以用于执行各种集合操作。
为了执行两个集合之间的并集,我们使用 addAll()方法。例如,
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); //两个集合的并集 numbers.addAll(evenNumbers); System.out.println("Union is: " + numbers); } }
输出结果
TreeSet1: [2, 4] TreeSet2: [1, 2, 3] 并集: [1, 2, 3, 4]
为了执行两个集合之间的交集,我们使用retainAll()方法。例如,
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); // 两个集合的交集 numbers.retainAll(evenNumbers); System.out.println("集合的交集: " + numbers); } }
输出结果
TreeSet1: [2, 4] TreeSet2: [1, 2, 3] 集合的交集: [2]
要计算两组之间的差集,我们可以使用removeAll()方法。例如,
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); //集合的差集 numbers.removeAll(evenNumbers); System.out.println("差集: " + numbers); } }
输出结果
TreeSet1: [2, 4] TreeSet2: [1, 2, 3, 4] 差集: [1, 3]
为了检查一个集合是否是另一个集合的子集,我们使用containsAll()方法。例如,
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); //检查primeNumbers是否为numbers子集 boolean result = numbers.containsAll(primeNumbers); System.out.println("TreeSet2是TreeSet1的子集吗? " + result); } }
输出结果
TreeSet1: [1, 2, 3, 4] TreeSet2: [2, 3] TreeSet2是TreeSet1的子集吗? True
方法 | 描述 |
---|---|
clone() | 创建TreeSet的副本 |
contains() | 在TreeSet中搜索指定的元素并返回布尔结果 |
isEmpty() | 检查是否TreeSet为空 |
size() | 返回TreeSet的大小 |
clear() | 从TreeSet中删除所有元素 |
TreeSet和HashSet都实现了Set接口。然而,它们之间存在着一些区别。
与HashSet不同,TreeSet中的元素是以某种顺序存储的。这是因为TreeSet还实现了SortedSet接口。
TreeSet提供了一些易于导航的方法。 例如first(),last(),headSet(),tailSet()等。这是因为TreeSet还实现了NavigableSet接口。
对于添加、删除、包含和大小等基本操作,HashSet比TreeSet更快。
在以上所有示例中,树集元素都是自然排序的。但是,我们也可以自定义元素的顺序。
为此,我们需要创建自己的comparator类,基于对树集中的元素进行排序。例如
import java.util.TreeSet; import java.util.Comparator; class Main { public static void main(String[] args) { //使用自定义比较器创建TreeSet TreeSet<String> animals = new TreeSet<>(new CustomComparator()); animals.add("Dog"); animals.add("Zebra"); animals.add("Cat"); animals.add("Horse"); System.out.println("TreeSet: " + animals); } //创建一个比较器类 public static class CustomComparator implements Comparator<String> { @Override public int compare(String animal1, String animal2) { int value = animal1.compareTo(animal2); //元素以相反的顺序排序 if (value > 0) { return -1; } else if (value < 0) { return 1; } else { return 0; } } } }
输出结果
TreeSet: [Zebra, Horse, Dog, Cat]
在上面的示例中,我们创建了一个树集,将CustomComparator类作为参数传递。
CustomComparator类实现了Comparator接口。
然后,我们重写compare()方法。现在,该方法将以相反的顺序对元素进行排序。