Java基础——HashSet和TreeSet类

本文主要介绍Java中HashSet和TreeSet。HashSet添加元素时,先算哈希值确定索引位置,若该位置有元素,会比较哈希值和用equals方法判断是否添加成功。TreeSet添加对象须为同类,可自动排序,有自然排序和定制排序两种方式。

文章目录

HashSet

源码

  • 添加元素的过程:

先调用该元素所属类的hashCode()方法计算哈希值,再处理得到底层数组的索引位置。

如果得到的索引位置上已经有元素,二者的哈希值不一定是一样。这时,比较哈希值,如果相同,再用equals()方法比较,如果返回为true,添加失败。

如果哈希值相同而且用equals()方法比较返回为false,用链表的方式添加到这个元素的后面,即原来的元素指向新添加的元素。

*哈希值计算方法:
哈希值相当于是一个随机数。
乘数一般选31,因为31相当于2的5次方,即左移5位,而且31是一个素数,只会被1和自己整除。

TreeSet

添加的对象必须是相同类,可以自动排序。
默认从小到大排序,如果想从大到小排序,compareTo()方法返回负值

自然排序中用对象所属类的compareTo()方法比较
定制排序是向TreeSet的构造器传入Comparator对象,用重写的compare()方法来排序。

### HashSet TreeSet 的区别 #### 数据结构 `HashSet` 是基于哈希表实现的集合,内部使用 `HashMap` 来存储数据[^1]。它依赖于对象的 `hashCode()` 方法来计算散列码并决定元素的存储位置。如果两个对象具有相同的散列码,则会调用其 `equals()` 方法进一步确认是否为相同对象。 相比之下,`TreeSet` 使用红黑树作为底层数据结构,因此它是有序的,并且默认按照自然顺序排列元素(即实现了 `Comparable` 接口的对象),或者通过指定的比较器 (`Comparator`) 进行排序[^2]。 --- #### 性能表现 由于 `HashSet` 利用了哈希机制,在理想情况下可以提供常数时间复杂度 O(1) 的基本操作(如添加、删除查找)。然而,当发生大量冲突时性能可能会退化到线性级别 O(n),这取决于具体实现以及负载因子等因素的影响[^3]。 而 `TreeSet` 提供的时间复杂度则较为稳定:对于插入、删除查询等主要功能而言均为对数阶 O(log n)[^2]。这是因为每次调整都需要重新平衡二叉搜索树的缘故。 --- #### 存储顺序 一个显著特点是 `HashSet` 不保证任何特定迭代次序;也就是说即使两次运行同一程序也可能得到不同的枚举序列[^1]。相反地,`TreeSet` 能够维持升序或降序关系视乎初始化参数设置如何定义[^2]。 --- #### 内存消耗 通常来说,因为额外维护了一个关联数组用于解决碰撞问题等原因使得 `HashSet` 可能在某些场合下占用更多内存空间相比起简单链表形式链接节点的传统方式。与此同时,“为了保持键值之间相对固定的逻辑联系”,`TreeSet` 需要保存指向父结点与子结点指针的信息,所以一般也会比单纯依靠位图标记存在的方案耗费更多的RAM资源[^3]。 --- #### 特殊情况处理能力 值得注意的是,尽管两者都继承自抽象基 AbstractSet 并遵循 Set 接口规范要求不允许存在重复成员项的规定,但在面对 null 值支持方面存在一定差异——`HashSet` 完全接受单个唯一null引用加入其中;但是标准版本下的 `TreeSet` 默认拒绝接纳任何形式上的NullPointer实例除非特别定制了允许如此行为的发生规则。 ```java // Example demonstrating Null handling difference between HashSet and TreeSet. import java.util.*; public class Main { public static void main(String[] args){ Set<String> hashSetExample = new HashSet<>(); Set<String> treeSetExample = new TreeSet<>(); try{ hashSetExample.add(null); System.out.println("Added 'null' successfully into HashSet."); // This line would throw NullPointerException when uncommented due to default behavior of TreeSet against nulls. //treeSetExample.add(null); System.out.println("Attempting addition failed as expected for TreeSet without custom comparator allowing null."); }catch(Exception e){ System.err.println(e.getMessage()); } System.out.println("\nContents after operations:"); System.out.println("HashSet contains: "+hashSetExample); System.out.println("TreeSet contains: "+treeSetExample); } } ``` --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值