`

HashSet的实现原理

阅读更多

1.HashSet概述:

  HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。HashSet中不允许有重复元素,这是因为HashSet是基于HashMap实现的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个private static final Object PRESENT = new Object();。HashSet跟HashMap一样,都是一个存放链表的数组。

  HashSet中add方法调用的是底层HashMap中的put()方法,而如果是在HashMap中调用put,首先会判断key是否存在,如果key存在则修改value值,如果key不存在这插入这个key-value。而在set中,因为value值没有用,也就不存在修改value值的说法,因此往HashSet中添加元素,首先判断元素(也就是key)是否存在,如果不存在这插入,如果存在着不插入,这样HashSet中就不存在重复值。

 

Hashtable 也是一个散列表,它存储的内容是键值对(key-value)映射
Hashtable 继承于Dictionary,实现了Map、Cloneable、java.io.Serializable接口。
Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。此外,Hashtable中的映射不是有序的。

Hashtable 的实例有两个参数影响其性能:初始容量 和 加载因子。容量 是哈希表中桶 的数量,初始容量 就是哈希表创建时的容量。注意,哈希表的状态为 open:在发生“哈希冲突”的情况下,单个桶会存储多个条目,这些条目必须按顺序搜索。加载因子 是对哈希表在其容量自动增加之前可以达到多满的一个尺度。初始容量和加载因子这两个参数只是对该实现的提示。关于何时以及是否调用 rehash 方法的具体细节则依赖于该实现。
通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查找某个条目的时间(在大多数 Hashtable 操作中,包括 get 和 put 操作,都反映了这一点)。

2.HashSet的实现:

  对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,更确切的说,HashSet中的元素,只是存放在了底层HashMap的key上, 而value使用一个static final的Object对象标识。因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成

 

Set的实现类的集合对象中不能够有重复元素,HashSet也一样他是使用了一种标识来确定元素的不重复,HashSet用一种算法来保证HashSet中的元素是不重复的,   HashSet采用哈希算法,底层用数组存储数据。默认初始化容量16,加载因子0.75

     Object类中的hashCode()的方法是所有子类都会继承这个方法,这个方法会用Hash算法算出一个Hash(哈希)码值返回,HashSet会用Hash码值去和数组长度取模, 模(这个模就是对象要存放在数组中的位置)相同时才会判断数组中的元素和要加入的对象的内容是否相同,如果不同才会添加进去。

     Hash算法是一种散列算法。

  Set hs=new HashSet();
 
  hs.add(o);
     |
         o.hashCode();
     |
  o%当前总容量  (0--15)
     |            
     |                 不发生冲突
        是否发生冲突-----------------直接存放
     |
     | 发生冲突
     |                  假(不相等)
        o1.equals(o2)-------------------找一个空位添加
     |
     |  是(相等)
         不添加
 
       覆盖hashCode()方法的原则:
       1、一定要让那些我们认为相同的对象返回相同的hashCode值
       2、尽量让那些我们认为不同的对象返回不同的hashCode值,否则,就会增加冲突的概率。
       3、尽量的让hashCode值散列开(两值用异或运算可使结果的范围更广)

       HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成,我们应该为保存到HashSet中的对象覆盖hashCode()和equals(),因为再将对象加入到HashSet中时,会首先调用hashCode方法计算出对象的hash值,接着根据此hash值调用HashMap中的hash方法,得到的值& (length-1)得到该对象在hashMap的transient Entry[] table中的保存位置的索引,接着找到数组中该索引位置保存的对象,并调用equals方法比较这两个对象是否相等,如果相等则不添加,注意:所以要存入HashSet的集合对象中的自定义类必须覆盖hashCode(),equals()两个方法,才能保证集合中元素不重复。在覆盖equals()和hashCode()方法时, 要使相同对象的hashCode()方法返回相同值,覆盖equals()方法再判断其内容。为了保证效率,所以在覆盖hashCode()方法时, 也要尽量使不同对象尽量返回不同的Hash码值。

 如果数组中的元素和要加入的对象的hashCode()返回了相同的Hash值(相同对象),才会用equals()方法来判断两个对象的内容是否相同。

 

 

http://blog.csdn.net/zheng0518/article/details/42199477

http://blog.sina.com.cn/s/blog_94cf845f0102vklz.html

http://www.cnblogs.com/xwdreamer/archive/2012/06/03/2532999.html

分享到:
评论

相关推荐

    Java面试题 从源码角度分析HashSet实现原理

    HashSet实现原理分析 HashSet是Java集合框架中的一种Set实现,HashSet实现了Set接口,提供了无序、不可重复的集合操作。通过源码分析, HashSet的实现原理可以分为以下几个方面: 1. HashSet的构造函数:HashSet的...

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

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

    Java面试题之HashSet的实现原理

    Java HashSet的实现原理 HashSet是Java集合框架中的一种set实现,它的实现原理主要基于HashMap。下面我们将详细介绍HashSet的实现原理。 首先,HashSet是Set的一个实现,所以它保证了其中没有重复的元素。在...

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

    HashSet作为Java集合框架中一个重要的非同步集合实现,它在JDK 7.0中的底层实现原理是基于HashMap来存储和操作数据的。下面就详细介绍HashSet的实现原理。 首先,HashSet是Set接口的一个实现类,它用于存储唯一性的...

    c++用vector实现HashSet

    虽然C++标准库中没有直接提供HashSet类,但我们可以利用其他容器,如`std::unordered_set`来实现类似的功能。不过,在这个场景中,我们将探讨如何使用`std::vector`来模拟HashSet的行为。 `std::vector`是C++标准库...

    HashMap底层实现原理HashMap与HashTable区别HashMap与HashSet区别.docx

    与HashSet的区别在于,HashSet是基于HashMap实现的集合类,用于存储唯一对象。HashSet中的元素没有顺序,添加元素时,HashSet会将元素转化为键放入HashMap中。因此,HashSet的插入和查找速度与HashMap相当,但由于...

    HashSet去重

    ### HashSet去重原理详解 #### 一、概述 在Java编程语言中,`HashSet`是一种常用的集合类,属于`java.util`包的一部分。它不允许集合中有重复的元素,并且不保证集合中元素的顺序。`HashSet`之所以能够实现去重...

    hashset类的使用

    在Java语言中,HashSet类是集合框架的重要组成部分,属于Set接口的一个实现。它基于哈希表的原理来存储不重复的元素,其核心在于利用哈希算法快速定位元素存储位置,从而提高数据存取的效率。本篇将详细介绍Java语言...

    Java集合容器面试题(2022最新版)-重点.docx

    #### HashSet实现原理 - 基于`HashMap`实现,使用键值对中的键来存储数据,值始终为`PRESENT`。 - 通过散列算法计算元素的哈希码,然后根据哈希码找到存储位置。 #### HashSet如何检查重复 - 通过元素的`equals()`...

    集合的概念及应用和HashSet保证数据不重复的原理

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

    史上最全java面试,103项重点知识,带目录

    24. **HashSet实现原理**: HashSet基于HashMap实现,每个元素作为HashMap的一个键,键的值是固定的。 【多线程】 25. **并行与并发**: 并行指多任务同时执行,而并发是交替执行,看起来同时进行。 26. **线程...

    集合类HashSet

    在Java编程语言中,集合类是用于存储一组...在黑马程序员_毕向东_Java基础视频教程中,你可能会更详细地学习到关于HashSet的实现原理和实战技巧。通过观看相关视频和实践操作,可以加深对HashSet的理解,提升编程能力。

    排序之HashSet和TreeSet的区别

    在Java编程语言中,集合框架是处理数据的重要组成部分,其中`...同时,源码阅读也是提升技能的好方法,通过查看`HashSet`和`TreeSet`的源码,可以更深入地了解它们的工作原理,这有助于优化代码并解决可能出现的问题。

    java 利用HashSet删除学生

    在Java编程中,HashSet是一个非常重要的集合类,它继承自AbstractSet并实现了Set接口。HashSet不包含重复元素,也不保持...通过理解HashSet的工作原理和其提供的方法,能够更好地优化我们的代码,提高程序的执行效率。

    HashSet和TreeSet.doc

    HashSet 和 TreeSet 是 Java 中两种常用的 Set 集合实现,它们都继承自 Set 接口,但实现方式和特性上存在显著差异。 首先,HashSet 是基于哈希表(HashMap 实例)来存储元素的,因此它提供了快速的插入、删除和...

Global site tag (gtag.js) - Google Analytics