`
wolfcame
  • 浏览: 79080 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

HashSet的重复值判定逻辑

    博客分类:
  • J2SE
阅读更多
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保证数据不重复的原理

    关于“HashSet保证数据不重复的原理”,这涉及到HashSet内部的实现。HashSet基于HashMap实现,每个元素都是HashMap的一个键。在添加元素时,HashSet会调用对象的hashCode()方法生成哈希码,然后根据哈希码快速定位...

    HashSet的实现原理

    在Java编程中,HashSet是一种不允许存储重复元素的集合,它实现了Set接口。HashSet是通过HashMap来实现的,其底层使用HashMap来保存所有元素。这种实现方式让HashSet的操作非常简单高效,因为HashSet的大部分操作,...

    hashset产生不重复随机数

    利用hashset产生不重复随机数的函数,附含测试数据; 调用方法 int[] arr=noDup(max,num),max为最大的数,num为要产生的随机数个数

    hashset类的使用

    当添加元素到HashSet时,实际上是将元素作为Map的键来存储,而值则统一为一个虚拟的固定对象。由于HashMap的键是唯一的,所以通过这种方式,HashSet能够确保所有元素的唯一性。 接下来,我们看看HashSet类提供的...

    HashSet去重

    为了确保`HashSet`正确地识别重复元素,用户自定义的类必须重写`equals`和`hashCode`方法,以保证逻辑一致性。此外,`HashSet`不仅在去重方面表现出色,还在性能上具有明显优势,特别是在处理大数据量的情况下。

    HashSet类的用法.pdf

    3. **允许一个null元素**:`HashSet`允许存在一个`null`值的元素。 #### 三、基本用法 1. **创建`HashSet`对象** ```java HashSet&lt;String&gt; hs = new HashSet(); ``` 2. **添加元素** 使用`add()`方法向`...

    HashSet详解和使用示例_动力节点Java学院整理

    HashSet中的每个元素被视为HashMap的一个键(key),而值(value)通常是常量`PRESENT`,用来满足HashMap的键值对需求。这样,HashSet通过HashMap实现了元素的存储和去重功能。 ### HashSet与Map的关系 HashSet并不...

    HashMap与HashTable和HashSet的区别

    `HashSet`是一个不包含重复元素的`Set`,它是由`HashMap`实现的。`HashSet`实际上就是`HashMap`的一个特殊应用,其将所有值映射为`null`。这意味着`HashSet`不允许`null`值,但允许一个`null`键(即一个`null`元素)...

    集合类HashSet

    HashSet是其中的一种,它属于集合框架的一部分,提供了一种基于哈希表实现的无序、不可重复的元素集合。本文将深入探讨HashSet类及其相关的知识点。 首先,HashSet是由HashMap内部实现的,它利用了键值对(key-...

    treemap treeset hashset hashmap 简要介绍

    `HashSet`的底层使用了`HashMap`,实际上,`HashSet`内部就是一个`HashMap`,其中所有值都被设置为`null`。 ### HashMap `HashMap`是基于哈希表实现的`Map`接口,它提供了快速的插入、删除和查找操作。`HashMap`...

    java集合-HashSet的使用

    无序性:HashSet 中的元素没有特定的顺序,不能按照插入顺序或者元素值的方式进行访问。如果需要按照特定顺序遍历元素,可以考虑使用 LinkedHashSet。 不重复性:HashSet 中的元素必须是唯一的,不允许包含重复元素...

    HashSet工作原理_动力节点Java学院整理

    对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSet 的源代码,可以看到如下代码:

    源码解析jdk7.0集合:HashSet的底层实现原理.pdf

    所谓唯一性,指的是HashSet中不允许出现重复的元素,同时,它也允许存储null值。Set集合的特点是无序的,也就是说,集合中的元素没有固定的顺序,且不能通过索引位置访问元素。 HashSet的存储结构基于HashMap来实现...

    java HashSet 集合排序

    java HashSet 集合排序,需要通过利用TreeSet集合排序。2013-10-30。

    排序之HashSet和TreeSet的区别

    它允许存储null值,但不允许存储重复元素。`HashSet`的核心优点在于其快速的插入、删除和查找操作,时间复杂度通常为O(1)。这是因为`HashSet`通过哈希函数计算元素的位置,只要哈希函数设计得合理,冲突少,就能快速...

    hashSet底层去重原理.xmind

    hashSet底层去重原理

    Java基础加强_ArrayList_HashSet的比较及Hashcode分析

    4. 是否允许重复:ArrayList允许,HashSet不允许。 5. 使用场景:ArrayList适合需要按顺序访问元素的情况,HashSet适合需要快速查找、插入和删除且不关心顺序的场景。 在实际开发中,选择ArrayList还是HashSet应...

    HashSet和TreeSet.doc

    Set是java中一个不包含重复元素的collection。更正式地说,set 不包含满足e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。 HashSet与TreeSet...

Global site tag (gtag.js) - Google Analytics