Java 中的 TreeSet、LinkedHashSet 和 HashSet 是集合框架中的三个 Set 实现,与许多其他集合一样,它们也用于存储对象。 TreeSet 的主要特点是排序,LinkedHashSet 是插入顺序,HashSet 只是用于存储对象的通用集合。 HashSet 是使用 Java 中的 HashMap 实现的,而 TreeSet 是使用 TreeMap 实现的。 TreeSet 是一个 SortedSet 实现,它允许它将元素保持在由 Comparable 或 Comparator 接口定义的排序顺序中。 Comparable 用于自然顺序排序,Comparator 用于对象的自定义顺序排序,可以在创建 TreeSet 实例时提供。无论如何,在看到 TreeSet、LinkedHashSet 和 HashSet 之间的区别之前,让我们看看它们之间的一些相似之处:
1) Duplicates : 所有三个实现 Set 接口意味着它们不允许存储重复。
2) 线程安全:HashSet、TreeSet 和 LinkedHashSet 不是线程安全的,如果你在至少有一个线程修改 Set 的多线程环境中使用它们,你需要在外部同步它们。
3) Fail-Fast Iterator:TreeSet、LinkedHashSet、HashSet返回的Iterator都是fail-fast Iterator。即,如果 Iterator 在创建后通过 Iterators remove() 方法以外的任何方式进行了修改,它将尽最大努力抛出 ConcurrentModificationException。在此处阅读有关快速故障与故障安全迭代器的更多信息
现在让我们看看 Java 中 HashSet、LinkedHashSet 和 TreeSet 的区别:
性能和速度:它们之间的第一个区别在于速度。 HashSet 最快,LinkedHashSet 在性能上排名第二或几乎与 HashSet 相似,但 TreeSet 速度稍慢,因为它需要在每次插入时执行排序操作。 TreeSet 为添加、删除和包含等常见操作提供有保证的 O(log(n)) 时间,而 HashSet 和 LinkedHashSet 提供恒定的时间性能,例如给定哈希函数的添加、包含和删除 O(1) 将元素均匀分布在桶中。
Ordering : HashSet 不维护任何顺序,而 LinkedHashSet 维护元素的插入顺序,很像 List 接口,TreeSet 维护排序或元素的顺序。
内部实现:HashSet 由 HashMap 实例支持,LinkedHashSet 由 HashSet 和 LinkedList 实现,而 TreeSet 由 Java 中的 NavigableMap 支持,默认使用 TreeMap。
null : HashSet 和 LinkedHashSet 都允许 null 但 TreeSet 不允许 null 但 TreeSet 不允许 null 并在将 null 插入 TreeSet 时抛出 java.lang.NullPointerException。由于 TreeSet 使用各个元素的 compareTo() 方法来比较它们,在与 null 比较时抛出 NullPointerException,这里是一个