首先,最重要的,HashMap

 作为一个我们使用非常多的集合。最常被大家认知的是,它是一个key-value形式存储数据的数据结构,可以实现快速的存,取操作。
 关于HashMap的源码,我们截取一部分分析:
   
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
{ /**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 /**
* The maximum capacity, used if a higher value is implicitly specified
* by either of the constructors with arguments.
* MUST be a power of two <= 1<<30.
*/
static final int MAXIMUM_CAPACITY = 1 << 30; /**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f; /**
* An empty table instance to share when the table is not inflated.
*/
static final Entry<?,?>[] EMPTY_TABLE = {}; /**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;

  

   我们看到了它实现的接口有Serializable,说明他能序列化,有Cloneable,说明能被克隆,有Map<K,V>,说明是一个Map(废话)。还有几条有用的信息:第一:有个默认初始容量,第二:有个最大容量,第三:有个调节因子,第四:有个数组。
   再往后看,发现这玩意又是由一个数组组成的,而这个数组的初始容量是16,最大容量是2^30。当然这个调节因子这个地方暂且不提。
   既然是用数组存储,我们存的又是Key-Value形式,这数组是怎么运作的呢?这里用往Map中添加数据为例说明:
 
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
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;
} 
   由于篇幅问题,我们就不粘贴太多代码了,先说一下,我们的hashMap实现是有一个数组实现,数组中存储的都是Entry<Key,Value>节点,Entry是HashMap的内部类,存储的是key,value,key的哈希值和下一个节点,具体可以自己查看源码。
  这里我们看到,首先,如果这个数字为空,则先初始化一个数组,如果要添加的key为空,直接进行空Key的添加(这里HashMap是允许有一个key为空的值的)。如果key不为空,则算出key的哈希值,根据哈希值,查找对应数组的位置,如果此key存在,就是说有相同的key,则覆盖(其实是链到后面的串,每个数组元素往后一个链表),没有则直接添加。这么一说其实就简单了,我们查询什么的就可以根据哈希值直接定位到相应的Entry,然后扔出来就是了。
 

然后我们说说HashSet:

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L; private transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object(); /**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}

这里就可以看出,HashSet底层就是一个HashMap,而它跟HashMap不同的就是它是实现Set接口,所以他的数据必须唯一。

最后是HashTable:

由于篇幅问题,就不贴代码了,跟HashMap差不多,底层也是一个数组。就说一下它跟HashMap主要的区别吧:

 第一:HashMap允许一个null的key和任意value都有null,而HashTable无论key和value都不能为空。
 第二:HashTable可以看做是线程安全的HashMap。

关于HashMap,HashTable,HashSet浅析的更多相关文章

  1. [置顶] HashMap HashTable HashSet区别剖析

    HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...

  2. HashMap HashTable HashSet

    原文转载自 http://blog.csdn.net/wl_ldy/article/details/5941770 HashMap是新框架中用来代替HashTable的类 也就是说建议使用HashMa ...

  3. HashMap HashTable HashSet区别剖析

    HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...

  4. 六.HashMap HashTable HashSet区别剖析总结

    HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面: 1.HashSet底层采用 ...

  5. Java中ArrayList,Vector,LinkedList,HashMap,HashTable,HashSet对比及总结

    1.所有的集合的父类都是Collection的接口 2.Set List Map 区别 A  在Set里面:无法添加元素的顺序,所以Set里面的元素不能重复 B  在List中:有索引号,类似于数组, ...

  6. Set ,List,ArrayList,LinkedList,Vectory,HashMap,Hashtable,HashSet,TreeSet,TreeSet

    Set与List区别: 两者都是接口,并继承Collection接口:List有序,允许重复:Set无序,不能重复: ArrayList与LinkList区别: ArrayList是动态数组,查询效率 ...

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

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

  8. java该HashTable,HashMap和HashSet

    同一时候我们也对HashSet和HashMap的核心方法hashcode进行了具体解释,见<探索equals()和hashCode()方法>. 万事俱备,那么以下我们就对基于hash算法的 ...

  9. HashMap与HashTable的区别、HashMap与HashSet的关系

    http://blog.csdn.net/wl_ldy/article/details/5941770 HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是 ...

  10. (转)HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别

    ①HashMap的工作原理 HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象.当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算h ...

随机推荐

  1. R语言操作mysql上亿数据量(ff包ffbase包和ETLUtils包)

    平时都是几百万的数据量,这段时间公司中了个大标,有上亿的数据量. 现在情况是数据已经在数据库里面了,需要用R分析,但是完全加载不进来内存. 面对现在这种情况,R提供了ff, ffbase , ETLU ...

  2. [DevOps] 认识一下

    大家都在说DevOps(Develop Operation),大概知道就是开发和运维沟通交流,一条线,然后使产品能够顺利的.短时间内上线.维稳什么的. 今天特意看了下 DockOne里面的一篇文章,再 ...

  3. delphi 改变闪动光标

    delphi 改变闪动光标 // 不同风格的光标 procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;Shift ...

  4. LeetCode:数组中的第K个最大元素【215】

    LeetCode:数组中的第K个最大元素[215] 题目描述 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: ...

  5. python之路 前段之html,css

    一.HTML 超级文本标记语言是标准通用标记语言下的一个应用,也是一种规范,一种标准, 它通过标记符号来标记要显示的网页中的各个部分.网页文件本身是一种文本文件,通过在文本文件中添加标记符,可以告诉浏 ...

  6. master: Error: JAVA_HOME is not set and could not be found.问题解决

  7. 介绍Web项目中用到的几款JS日历日期控件和JS文本编辑框插件

    第一款日历日期控件:layDate 官方网站:http://laydate.layui.com/ 第二款日历日期控件:my97 官方网站:http://www.my97.net/ 第三款 文本编辑器控 ...

  8. Linux下的sed命令使用详解

    sed是stream editor的简称,也就是流编辑器.它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”pattern space,接着用sed命令处理缓冲区中的内容, ...

  9. Python 私有化属性

    # 对象的基本理论 # 什么事对象? # 万物皆对象 # 对象是具体物体 # 拥有属性 # 拥有行为 # 把很多零散的东西,封装成为一个整体 # 举例:王二小 # 属性 # 姓名 # 年龄 # 身高 ...

  10. Record and accumulation

    最近有同学在准备校招的问题,问我几个问题,我觉得有必要把大家的问题汇总下: 1.在设计变量的while指挥时候,可以利用弹栈的特性以及Java传值 只是传递的副本  去控制 : https://www ...