原文: https://howtodoinjava.com/java/collections/java-treeset-class/
Java TreeSet类扩展了 AbstractSet和实现了NavigableSet接口。 它与HashSet类非常相似,除了它以排序顺序存储元素。
排序顺序可以是自然顺序,也可以是树集合创建时提供的比较器的排序顺序,具体取决于所使用的构造器。
Table of Contents1\. TreeSet Hierarchy2\. TreeSet Features3\. TreeSet Constructors4\. TreeSet Methods5\. TreeSet Example6\. TreeSet Usecases7\. TreeSet Performance8\. Conclusion
1. TreeSet层次结构
TreeSet类扩展了AbstractSet类并实现了NavigableSet接口。 NavigableSet接口以层次结构顺序扩展SortedSet。
class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable
{
//implementation
}

树集合层次结构
2. TreeSet 特性
- 它扩展了
AbstractSet类,扩展了AbstractCollection类。 - 它实现了
NavigableSet接口,该接口扩展了SortedSet接口。 TreeSet中不允许重复的值。- 在
TreeSet中不允许NULL。 - 这是一个有序集合,它按排序顺序存储元素。
- 像
HashSet一样,此类为基本操作(添加,删除,包含和调整大小)提供恒定的时间性能。 TreeSet不允许插入异构对象,因为它必须比较对象以确定排序顺序。TreeSet没有同步。 如果多个线程同时访问哈希集合,并且至少有一个线程修改了哈希集合,则必须在外部对其进行同步。- 使用
Collections.synchronizedSortedSet(new TreeSet())方法来获取同步的TreeSet。 - 此类的迭代器方法返回的迭代器为快速失败,并且如果在创建迭代器后的任何时间修改了集合,则可能会抛出
ConcurrentModificationException,除了通过迭代器自己的remove()方法之外 。 TreeSet还实现了Searlizable和Cloneable接口。
3. TreeSet构造器
TreeSet具有四个可能的构造器:
TreeSet():创建一个新的空树集合,并根据其元素的自然顺序对其进行排序。TreeSet(Comparator c):创建一个新的空树集合,该树集合根据指定的比较器进行排序。TreeSet(SortedSet s):创建一个新树集合,其中包含与指定排序集相同的元素并使用相同的顺序。TreeSet(Collection c):创建一个新树集合,其中包含指定集合中的元素,并根据其元素的自然顺序对其进行排序。
4. TreeSet方法
boolean add(E e):如果指定的元素尚不存在,则将其添加到Set中。Comparator comparator():返回用于对该集合中的元素进行排序的比较器;如果此集合使用其元素的自然排序,则返回null。Object first():返回此集合中当前的第一个(最小)元素。Object last():返回当前在此集合中的最后一个(最大)元素。void clear():从TreeSet中删除所有元素。boolean contains(Object o):如果TreeSet包含指定的元素,则返回true,否则返回false。boolean isEmpty():如果TreeSet不包含任何元素,则返回true,否则返回false。int size():返回TreeSet中的元素数。Iterator<E> iterator():以升序返回此集合中元素的迭代器。Iterator<E> endingIterator():以降序返回此集合中元素的迭代器。NavigableSet<E> endingSet():返回此集合中包含的元素的逆序视图。boolean remove(Object o):从TreeSet中删除指定的元素(如果存在)并返回true,否则返回false。Object clone():返回TreeSet的浅表副本。Spliterator<E> spliterator():在此TreeSet中的元素上创建后绑定和快速失败的分隔符。 它与树集合提供的顺序相同。
5. TreeSet示例
5.1 TreeSet添加,删除,迭代器示例
//1\. Create TreeSet
TreeSet<String> TreeSet = new TreeSet<>();
//2\. Add elements to TreeSet
TreeSet.add("A");
TreeSet.add("B");
TreeSet.add("C");
TreeSet.add("D");
TreeSet.add("E");
System.out.println(TreeSet);
//3\. Check if element exists
boolean found = TreeSet.contains("A"); //true
System.out.println(found);
//4\. Remove an element
TreeSet.remove("D");
//5\. Iterate over values
Iterator<String> itr = TreeSet.iterator();
while(itr.hasNext())
{
String value = itr.next();
System.out.println("Value: " + value);
}
程序输出。
[A, B, C, D, E]
true
Value: A
Value: B
Value: C
Value: E
5.2 将TreeSet转换为数组示例
Java 示例,使用toArrray()方法将TreeSet转换为数组。
TreeSet<String> TreeSet = new TreeSet<>();
TreeSet.add("A");
TreeSet.add("B");
TreeSet.add("C");
TreeSet.add("D");
TreeSet.add("E");
String[] values = new String[TreeSet.size()];
TreeSet.toArray(values);
System.out.println(Arrays.toString(values));
程序输出:
[A, B, C, D, E]
5.3 将TreeSet转换为ArrayList示例
使用 Java 8 流 API 将TreeSet转换为ArrayList的 Java 示例。
TreeSet<String> TreeSet = new TreeSet<>();
TreeSet.add("A");
TreeSet.add("B");
TreeSet.add("C");
TreeSet.add("D");
TreeSet.add("E");
List<String> valuesList = TreeSet.stream().collect(Collectors.toList());
System.out.println(valuesList);
程序输出:
[A, B, C, D, E]
6. TreeSet用例
TreeSet非常类似于HashSet(唯一元素),并提供可预测的迭代顺序(排序)。 排序顺序可以使用自定义比较器覆盖。
TreeSet在引擎盖下使用红黑树。 因此,该集合可以视为动态搜索树。 当您需要一个经常进行读写操作并应保持秩序的结构时,TreeSet是一个不错的选择。
如果您想使集合保持排序,并且主要是在追加元素,那么带Comparator的TreeSet是最好的选择。
7. TreeSet性能
TreeSet为基本操作(添加,删除和包含)提供了保证的log(n)时间成本。- 像对元素进行排序一样的迭代操作需要花费
O(n)的时间。
8. 总结
从上面的讨论中可以明显看出,在我们要以排序方式处理重复记录的情况下,TreeSet是非常有用的集合类。 它还为基本操作提供了可预测的性能。
如果不需要元素的排序顺序,则建议改用较轻量的HashSet和HashMap。
在评论中向我发送有关 Java 中 TreeSet的问题。
学习愉快!
参考:
