TreeSet是 分类数据集接口 在Java中,使用 树 用于储存。元素的顺序由一个集合使用它们的自然顺序来维持,无论是否是显式排序 比较器 已提供。如果要正确实施该计划,这必须与equals保持一致 设置接口 .
它也可以由设置创建时提供的比较器进行排序,具体取决于使用的构造函数。TreeSet实现了一个 NavigableSet接口 通过继承 抽象集类 .
从上图可以清楚地看到,可导航集扩展了排序集接口。由于集合不保留插入顺序,可导航集合接口提供了在集合中导航的实现。实现可导航集的类是TreeSet,它是自平衡树的实现。因此,这个界面为我们提供了一种在这棵树中导航的方法。
注:
- 当且仅当相应的类实现了 可比界面 .
- 一串 班级和所有 包装类 已经实现了类似的接口,但是 StringBuffer类 实现可比较的接口。因此,我们没有获得 类别例外 在上面的例子中。
- 对于空树集,当尝试插入null作为第一个值时,将从JDK 7获得NPE。从JDK 7开始,TreeSet完全不接受null。然而,直到JDK 6,null被接受为第一个值,但是在树集合中插入更多的null值会导致NullPointerException。因此,它被认为是一个bug,因此在JDK 7中被删除。
- TreeSet是存储大量排序信息的最佳选择,由于其更快的访问和检索时间,这些信息应该能够快速访问。
- 在树集合中插入空值会引发 空指针异常 因为在插入null时,它会与现有元素进行比较,而null不能与任何值进行比较。
TreeSet在内部是如何工作的?
TreeSet基本上是一个自平衡二叉搜索树的实现,比如 红黑树 因此,像添加、删除和搜索这样的操作需要O(log(N))时间。原因是在自平衡树中,确保所有操作的树高度始终为O(log(N))。因此,这被认为是存储海量排序数据并对其执行操作的最有效的数据结构之一。然而,像按排序顺序打印N个元素这样的操作需要O(N)个时间。
现在,让我们在继续之前讨论同步树集。 树集的实现是不同步的。这意味着,如果多个线程同时访问一个树集,并且至少有一个线程修改了该树集,那么它必须在外部同步。这通常是通过同步一些自然发生的对象来实现的 封装 布景。如果不存在这样的对象,则应使用 收藏。同步分类数据集 方法这最好在创建时完成,以防止意外不同步地访问集合。可以实现如下所示:
TreeSet ts = new TreeSet(); Set syncSet = Collections.synchronziedSet(ts);
TreeSet类的构造函数如下:
为了创建TreeSet,我们需要创建TreeSet类的一个对象。TreeSet类由各种构造函数组成,这些构造函数允许创建TreeSet。以下是该类中可用的构造函数:
- TreeSet(): 此构造函数用于构建一个空TreeSet对象,元素将按默认的自然排序顺序存储在该对象中。
语法: 如果我们希望创建一个名为ts的空树集,那么可以将其创建为:
TreeSet ts = new TreeSet();
- TreeSet(比较器): 此构造函数用于构建一个空的TreeSet对象,其中的元素需要排序顺序的外部规范。
语法: 如果我们希望创建一个名为ts的空树集,并带有外部排序现象,那么可以创建如下:
TreeSet ts = new TreeSet(Comparator comp);
- TreeSet(系列): 此构造函数用于构建一个TreeSet对象,其中包含给定集合中的所有元素,元素将按默认的自然排序顺序存储在该集合中。简而言之,当需要从任何集合对象到TreeSet对象进行任何转换时,就会使用此构造函数。
语法: 如果我们希望创建一个名为ts的树集,那么可以按如下方式创建:
TreeSet t = new TreeSet(Collection col);
- 树集(分类集): 此构造函数用于构建一个TreeSet对象,其中包含给定对象中的所有元素 分类集 元素将以默认的自然排序顺序存储。简而言之,此构造函数用于将SortedSet对象转换为TreeSet对象。
语法: 如果我们希望创建一个名为ts的树集,那么可以按如下方式创建:
TreeSet t = new TreeSet(SortedSet s);
TreeSet类中的方法如下所示 以表格的形式,稍后我们将在实现部分展示。
树形工具 分类集 因此,它拥有所有收集方法的可用性, 设置 和 分类数据集接口 .以下是Treeset界面中的方法。下表中的“?”表示该方法适用于任何类型的对象,包括用户定义的对象。
方法 | 描述 |
---|---|
添加(对象o) | 此方法将根据创建树集期间提到的相同排序顺序添加指定元素。不会添加重复条目。 |
addAll(集合c) | 此方法将指定集合的所有元素添加到集合中。集合中的元素应该是同质的,否则将抛出ClassCastException。集合的重复条目将不会添加到TreeSet。 |
天花板(E) | 此方法返回集合中大于或等于给定元素的最小元素,如果没有此类元素,则返回null。 |
清除() | 此方法将删除所有元素。 |
克隆() | 该方法用于返回集合的浅层副本,这只是一个简单的复制集合。 |
比较器比较器 | 此方法将返回用于对TreeSet中的元素进行排序的比较器,如果使用默认的自然排序顺序,则将返回null。 |
包含(对象o) | 如果树集合中存在给定元素,此方法将返回true,否则将返回false。 |
下降迭代器?() | 此方法按降序返回该集合中元素的迭代器。 |
下降集?() | 此方法返回此集合中包含的元素的逆序视图。 |
第一() | 如果TreeSet不为null,此方法将返回TreeSet中的第一个元素,否则将抛出NoSuchElementException。 |
地板(E) | 此方法返回该集合中小于或等于给定元素的最大元素,如果没有此类元素,则返回null。 |
耳机(对象到元素) | 此方法将返回树集中小于指定元素的元素。 |
较高的?(E) | 此方法返回该集合中严格大于给定元素的最小元素,如果没有此类元素,则返回null。 |
isEmpty() | 如果此集合不包含任何元素,或者在相反的情况下为空且为false,则使用此方法返回true。 |
迭代器迭代器() | 返回迭代集合元素的迭代器。 |
最后() | 如果TreeSet不为null,此方法将返回TreeSet中的最后一个元素,否则将抛出NoSuchElementException。 |
降低(E) | 这个方法返回这个集合中最大的元素,严格小于给定的元素,如果没有这样的元素,则返回null。 |
首先是波莉?() | 此方法检索并删除第一个(最低)元素,如果此集合为空,则返回null。 |
波拉斯特?() | 此方法检索并删除最后一个(最高)元素,如果此集合为空,则返回null。 |
移除(对象o) | 此方法用于从集合中返回特定元素。 |
大小() | 此方法用于返回集合的大小或集合中存在的元素数。 |
拆分器() | 此方法在该集合中的元素上创建一个后期绑定且快速失效的拆分器。 |
子集(对象从元素、对象到元素) | 此方法将返回从Element到toElement的元素。fromElement是包含的,toElement是独占的。 |
tailSet(来自元素的对象) | 此方法将返回大于或等于指定元素的树集元素。 |
插图: 下面的实现演示了如何创建和使用树集。
JAVA
// Java program to Illustrate Working of TreeSet // Importing required utility classes import java.util.*; // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating a Set interface with reference to // TreeSet Set<String> ts1 = new TreeSet<>(); // Elements are added using add() method ts1.add( "A" ); ts1.add( "B" ); ts1.add( "C" ); // Duplicates will not get insert ts1.add( "C" ); // Elements get stored in default natural // Sorting Order(Ascending) System.out.println(ts1); } } |
[A, B, C]
实施:
在这里,我们将对TreeSet对象执行各种操作,以熟悉java中TreeSet的方法和概念。让我们看看如何在树集上执行一些常用的操作。具体如下:
- 添加元素
- 访问元素
- 移除元素
- 遍历元素
现在让我们在一个干净的java程序的帮助下逐个讨论每个操作。
操作1: 添加元素
为了向树集添加元素,我们可以使用 add()方法 。但是,插入顺序不会保留在树集中。在内部,每个元素的值都会按升序进行比较和排序。我们需要注意的是,不允许重复元素,并且忽略所有重复元素。而且,树集不接受空值。
实例
JAVA
// Java code to Illustrate Addition of Elements to TreeSet // Importing utility classes import java.util.*; // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating a Set interface with // reference to TreeSet class // Declaring object of string type Set<String> ts = new TreeSet<>(); // Elements are added using add() method ts.add( "Geek" ); ts.add( "For" ); ts.add( "Geeks" ); // Print all elements inside object System.out.println(ts); } } |
[For, Geek, Geeks]
操作2: 访问元素
添加元素后,如果我们希望访问这些元素,我们可以使用内置方法,如 包含() , 第一() , 最后() 等
实例
JAVA
// Java code to Illustrate Working of TreeSet by // Accessing the Element of TreeSet // Importing utility classes import java.util.*; // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating a NavigableSet object with // reference to TreeSet class NavigableSet<String> ts = new TreeSet<>(); // Elements are added using add() method ts.add( "Geek" ); ts.add( "For" ); ts.add( "Geeks" ); // Printing the elements inside the TreeSet object System.out.println( "Tree Set is " + ts); String check = "Geeks" ; // Check if the above string exists in // the treeset or not System.out.println( "Contains " + check + " " + ts.contains(check)); // Print the first element in // the TreeSet System.out.println( "First Value " + ts.first()); // Print the last element in // the TreeSet System.out.println( "Last Value " + ts.last()); String val = "Geek" ; // Find the values just greater // and smaller than the above string System.out.println( "Higher " + ts.higher(val)); System.out.println( "Lower " + ts.lower(val)); } } |
Tree Set is [For, Geek, Geeks]Contains Geeks trueFirst Value ForLast Value GeeksHigher GeeksLower For
操作3: 删除值
可以使用 删除() 方法有多种其他方法可用于删除第一个值或最后一个值。
实例
JAVA
// Java Program to Illustrate Removal of Elements // in a TreeSet // Importing utility classes import java.util.*; // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating an object of NavigableSet // with reference to TreeSet class // Declaring object of string type NavigableSet<String> ts = new TreeSet<>(); // Elements are added // using add() method ts.add( "Geek" ); ts.add( "For" ); ts.add( "Geeks" ); ts.add( "A" ); ts.add( "B" ); ts.add( "Z" ); // Print and display initial elements of TreeSet System.out.println( "Initial TreeSet " + ts); // Removing a specific existing element inserted // above ts.remove( "B" ); // Printing the updated TreeSet System.out.println( "After removing element " + ts); // Now removing the first element // using pollFirst() method ts.pollFirst(); // Again printing the updated TreeSet System.out.println( "After removing first " + ts); // Removing the last element // using pollLast() method ts.pollLast(); // Lastly printing the elements of TreeSet remaining // to figure out pollLast() method System.out.println( "After removing last " + ts); } } |
Initial TreeSet [A, B, For, Geek, Geeks, Z]After removing element [A, For, Geek, Geeks, Z]After removing first [For, Geek, Geeks, Z]After removing last [For, Geek, Geeks]
操作4: 在树集合中迭代
有多种方法可以遍历树集。最著名的是使用 增强的for循环 。而极客们大多会用这种方法迭代元素,同时在树集上练习问题,因为这是树、地图和图形问题中最常用的方法。
实例
JAVA
// Java Program to Illustrate Working of TreeSet // Importing utility classes import java.util.*; // Main class class GFG { // Main driver method public static void main(String[] args) { // Creating an object of Set with reference to // TreeSet class // Note: You can refer above media if geek // is confused in programs why we are not // directly creating TreeSet object Set<String> ts = new TreeSet<>(); // Adding elements in above object // using add() method ts.add( "Geek" ); ts.add( "For" ); ts.add( "Geeks" ); ts.add( "A" ); ts.add( "B" ); ts.add( "Z" ); // Now we will be using for each loop in order // to iterate through the TreeSet for (String value : ts) // Printing the values inside the object System.out.print(value + ", " ); System.out.println(); } } |
A, B, For, Geek, Geeks, Z,
树集的特征:
- TreeSet实现了 分类集 界面因此,不允许重复值。
- 树集中的对象按排序和升序存储。
- TreeSet不保留元素的插入顺序,但元素按键排序。
- 如果我们依赖于默认的自然排序顺序,那么插入到树中的对象应该是同质的和可比较的。TreeSet不允许插入异构对象。它会抛出一个 类别例外 在运行时,如果我们试图添加异构对象。
- TreeSet只能接受可比较的泛型类型。 例如,StringBuffer类实现了可比较的接口
JAVA
// Java code to illustrate What if Heterogeneous // Objects are Inserted // Importing all utility classes import java.util.*; // Main class class GFG { // Main driver method public static void main(String[] args) { // Object creation Set<StringBuffer> ts = new TreeSet<>(); // Adding elements to above object // using add() method ts.add( new StringBuffer( "A" )); ts.add( new StringBuffer( "Z" )); ts.add( new StringBuffer( "L" )); ts.add( new StringBuffer( "B" )); ts.add( new StringBuffer( "O" )); ts.add( new StringBuffer( 1 )); // Note: StringBuffer implements Comparable // interface // Printing the elements System.out.println(ts); } } |
[, A, B, L, O, Z]