HashSet是Set接口的一个具体实现类之一,它内部采用哈希算法,专门为快速查找而设计,它不允许插入重复的值,需要注意的问题是,存入HashSet的对象必须定义hashCode和equals方法。
下面我们来谈谈HashSet如何判定两个对象是否重复。
HashSet内部使用HashMap来保存对象,将需要存入的对象比如T a,以key的形式存入HashMap中,这可以从代码中看到:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
首先,说下HashMap内部是使用数组进行存储的,数组里存放的是HashMap的内部类Entry,它是一个自引用的类,支持链表结构,用于对哈希冲突的情况下保存多个对象。
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
final int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
public final K getKey() {
return key;
}
.........//略去大段代码
}
然后我们在HashMap的put方法中可以看到它是如何进行重复性判断的:
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
首先,可以通过key的hashCode,经过hash()函数的处理,得出一个i,这是这个对象应该存放的位置,然后去数组中查找第一个Entry,如何Entry不存在,直接进行添加操作;如果发现存在Entry,便对其进行遍历,使用条件(k = e.key) == key || key.equals(k)进行判断,如果为true,说明已经存在,便对其进行重新设置,但是因为hashSet使用的其实是key,value对其是没任何用处的。所以相当于没有任何改变。
这也就是我们为什么在使用HashSet存储自定义类时,需要重写hashCode()和equals()方法的原因,否则使用Object对象默认的hashCode()和equals方法,Object的hashCode()使用对象的地址计算散列码,使用内存地址进行equals()判定。这可能会出现你不想看到的结果。
分享到:
相关推荐
利用hashset产生不重复随机数的函数,附含测试数据; 调用方法 int[] arr=noDup(max,num),max为最大的数,num为要产生的随机数个数
关于“HashSet保证数据不重复的原理”,这涉及到HashSet内部的实现。HashSet基于HashMap实现,每个元素都是HashMap的一个键。在添加元素时,HashSet会调用对象的hashCode()方法生成哈希码,然后根据哈希码快速定位...
在Java编程中,HashSet是一种不允许存储重复元素的集合,它实现了Set接口。HashSet是通过HashMap来实现的,其底层使用HashMap来保存所有元素。这种实现方式让HashSet的操作非常简单高效,因为HashSet的大部分操作,...
当添加元素到HashSet时,实际上是将元素作为Map的键来存储,而值则统一为一个虚拟的固定对象。由于HashMap的键是唯一的,所以通过这种方式,HashSet能够确保所有元素的唯一性。 接下来,我们看看HashSet类提供的...
为了确保`HashSet`正确地识别重复元素,用户自定义的类必须重写`equals`和`hashCode`方法,以保证逻辑一致性。此外,`HashSet`不仅在去重方面表现出色,还在性能上具有明显优势,特别是在处理大数据量的情况下。
3. **允许一个null元素**:`HashSet`允许存在一个`null`值的元素。 #### 三、基本用法 1. **创建`HashSet`对象** ```java HashSet<String> hs = new HashSet(); ``` 2. **添加元素** 使用`add()`方法向`...
HashSet中的每个元素被视为HashMap的一个键(key),而值(value)通常是常量`PRESENT`,用来满足HashMap的键值对需求。这样,HashSet通过HashMap实现了元素的存储和去重功能。 ### HashSet与Map的关系 HashSet并不...
`HashSet`是一个不包含重复元素的`Set`,它是由`HashMap`实现的。`HashSet`实际上就是`HashMap`的一个特殊应用,其将所有值映射为`null`。这意味着`HashSet`不允许`null`值,但允许一个`null`键(即一个`null`元素)...
HashSet是其中的一种,它属于集合框架的一部分,提供了一种基于哈希表实现的无序、不可重复的元素集合。本文将深入探讨HashSet类及其相关的知识点。 首先,HashSet是由HashMap内部实现的,它利用了键值对(key-...
`HashSet`的底层使用了`HashMap`,实际上,`HashSet`内部就是一个`HashMap`,其中所有值都被设置为`null`。 ### HashMap `HashMap`是基于哈希表实现的`Map`接口,它提供了快速的插入、删除和查找操作。`HashMap`...
无序性:HashSet 中的元素没有特定的顺序,不能按照插入顺序或者元素值的方式进行访问。如果需要按照特定顺序遍历元素,可以考虑使用 LinkedHashSet。 不重复性:HashSet 中的元素必须是唯一的,不允许包含重复元素...
对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSet 的源代码,可以看到如下代码:
所谓唯一性,指的是HashSet中不允许出现重复的元素,同时,它也允许存储null值。Set集合的特点是无序的,也就是说,集合中的元素没有固定的顺序,且不能通过索引位置访问元素。 HashSet的存储结构基于HashMap来实现...
java HashSet 集合排序,需要通过利用TreeSet集合排序。2013-10-30。
它允许存储null值,但不允许存储重复元素。`HashSet`的核心优点在于其快速的插入、删除和查找操作,时间复杂度通常为O(1)。这是因为`HashSet`通过哈希函数计算元素的位置,只要哈希函数设计得合理,冲突少,就能快速...
hashSet底层去重原理
4. 是否允许重复:ArrayList允许,HashSet不允许。 5. 使用场景:ArrayList适合需要按顺序访问元素的情况,HashSet适合需要快速查找、插入和删除且不关心顺序的场景。 在实际开发中,选择ArrayList还是HashSet应...
Set是java中一个不包含重复元素的collection。更正式地说,set 不包含满足e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。 HashSet与TreeSet...