Dictionary(HashMap)的实现

 什么是哈希表?

  哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构。也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

为什么要了解字典类?

1.HashMap的性能最棒查找,添加,删除的时间复杂度都是常数。


Data Structure


Add


Find


Delete


GetByIndex

 Array (T[])
O(n)


O(n)


O(n)


O(1)

 Linked list (LinkedList<T>)
O(1)


O(n)


O(n)


O(n)

 Resizable array list (List<T>)
O(1)


O(n)


O(n)


O(1)

 Stack (Stack<T>)
O(1)


-


O(1)


-

 Queue (Queue<T>)
O(1)


-


O(1)


-

 Hash table (Dictionary<K,T>)
O(1)


O(1)


O(1)


-


Tree-based dictionary

(SortedDictionary<K,T>)


O(log n)


O(log n)


O(log n)


-


Hash table based set

(HashSet<T>)


O(1)


O(1)


O(1)


-


Tree based set

(SortedSet<T>)


O(log n)


O(log n)


O(log n)


-

2.举一反三。HashSet是基于HashMap来实现的,操作很简单,更像是对HashMap做了一次“封装”,而且只使用了HashMap的key来实现各种特性()

HashMap的原理?

  哈希表的做法其实很简单,就是把key通过一个固定的算法函数即所谓的哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。

而当使用哈希表进行查询的时候,就是再次使用哈希函数将key转换为对应的数组下标,并定位到该空间获取value,如此一来,就可以充分利用到数组的定位性能进行数据定位

put方法:


public V put(K key, V value) {

// 处理key为null,HashMap允许key和value为null

if (key == null)

return putForNullKey(value);

// 得到key的哈希码

int hash = hash(key);

// 通过哈希码计算出bucketIndex

int i = indexFor(hash, table.length);

// 取出bucketIndex位置上的元素,并循环单链表,判断key是否已存在

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;

}

}

// key不存在时,加入新元素

modCount++;

addEntry(hash, key, value, i);

return null;

}

 

 数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。那么我们能不能综合两者的特性,做出一种寻址容易,插入删除也容易的数据结构?答案是肯定的,这就是我们要提起的哈希表,哈希表有多种不同的实现方法,我接下来解释的是最常用的一种方法——拉链法,我们可以理解为“链表的数组”。

与其他集合的比较:

1.特点比较:


有序否


允许元素重复否


Collection




List




Set


AbstractSet




HashSet


TreeSet


是(用二叉树排序)


Map


AbstractMap



使用key-value来映射和存储数据,Key必须惟一,value可以重复


HashMap


TreeMap


是(用二叉树排序)

2.HashMap与Hashtable的区别:

HashMap是非synchronized,而Hashtable是synchronized(针对整张表的锁,性能不佳),HashMap可以 可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

3.由于HashMap不是线程安全的,在多线程环境中使用 ConcurrentHashMap。原因:其关键在于使用了锁分离技术, ConcurrentHashMap使用锁桶,默认将hash表分为16分桶,线程操作时锁定一个桶,这样,最多可以16个线程同时写入。大大提升并发性。而读方面,ConcurrentHashMap使用弱一致迭代器,当iterator被创建后数据改变时创新新的数据,完成后再将头指针替换为新数据。这保证了写的连续性和扩展性。

操作:

遍历:

Map map = new HashMap();
  Iterator iter = map.entrySet().iterator();
  while (iter.hasNext()) {
  Map.Entry entry = (Map.Entry) iter.next();
  Object key = entry.getKey();
  Object val = entry.getValue();

}

删除:

我们可以发现Dictionary在添加,删除元素按照如下方法进行:

通过Hash算法来计算到指定的Bucket上,碰撞到同一个Bucket槽上所有数据形成一个单链表

默认情况Entries槽中的数据按照添加顺序排列

删除的数据会形成一个 LinkedList的链表,添加数据的时候,优先向 LinkedList链表中添加数据, LinkedList为空则按照count依次排列。  HashMap在每个LinkedList节点中储存键值对对象。

参考:

http://developer.51cto.com/art/201507/485988.htm

http://kb.cnblogs.com/page/189480/

http://www.cnblogs.com/gaochundong/p/3813252.html

http://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs,1020c75d4d9aae74

http://visualgo.net/

http://www.admin10000.com/document/3322.html

http://blog.csdn.net/liuzhengkang/article/details/2916620

时间: 2024-10-06 21:19:58

Dictionary(HashMap)的实现的相关文章

HashTable Dictionary HashMap

脑海中一直存在两个Hash,一个是HashMap另一个是HashTable,今天来总结一下两者的区别 HashTable和HashMap 相同点:表示根据键的哈希代码进行组织的键/值对的集合. 区别:HashMap在C#中不存在的,而是在Java中 1.C#每一个元素都是存储在DictionaryEntry对象中的键/值对,键不能为 null,但值可以. 2.在Java的HashMap中,null可以作为键,这样的键只有一个:可以有一个或多个键所对应的值为null.当get()方法返回null值

java-HashMap分析

(一)哈希算法 哈希算法,将原始数据通过散列函数映射为较短的固定长度的二进制值,简称哈希值. hash算法有两个基本特点:可重复和不可逆.理论上计算出的哈希值是可重复的,但好的散列函数基本不会出现这种情况.不可逆指,知道哈希值无法推算出原始数据. 哈希算法一般用于快速查找(如HashMap)和加密算法(如MD5). (二)java中的hashcode java中对象基类Object有hashcode方法,native调用默认返回对象内存地址,hashcode返回不定长的10进制数. Java对于

Java集合之Hashtable源码分析

概述 Hashtable也是基于哈希表实现的, 与map相似, 不过Hashtable是线程安全的, Hashtable不允许 key或value为null. 成员变量 Hashtable的数据结构和HashMap一样, 采用 数组加链表的方式实现. 几个成员变量与HashMap一样: 方法 Hashtable的方法与HashMap基本一样, 只是 Hashtable方法加上了 synchronized 关键字, 保证Hashtable是线程安全的. 主要说说Hashtable与HashMap的

关于HashMap

1.什么是HashMap? 基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同.)此类不保证映射的顺序,特别是它不保证该顺序恒久不变.此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能. 2.与HashMap相关的HashTable表 Hash表也称散列表,也有直接译作哈希表,Hash表是一种特殊的数据结构,

HashMap与TreeMap源码分析

1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Java这么久,也写过一些小项目,也使用过TreeMap无数次,但到现在才明白它的实现原理).因此本着"不要重复造轮子"的思想,就用这篇博客来记录分析TreeMap源码的过程,也顺便瞅一瞅HashMap. 2. 继承结构 (1) 继承结构 下面是HashMap与TreeMap的继承结构: pu

HashTable vs HashMap(三)

HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable. 可能你觉得HashTable很好用,为什么不用呢?这里简单分析他们的区别. 1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样. 2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value

Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)

http://www.cnblogs.com/skywang12345/p/3311126.html 概要 学完了Map的全部内容,我们再回头开开Map的框架图. 本章内容包括:第1部分 Map概括第2部分 HashMap和Hashtable异同第3部分 HashMap和WeakHashMap异同 转载请注明出处:http://www.cnblogs.com/skywang12345/admin/EditPosts.aspx?postid=3311126 第1部分 Map概括 (01) Map

HashMap和Hashtable的区别

导读: 1 HashMap不是线程安全的 hastmap是一个接口 是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值.HashMap允许null key和null value,而hashtable不允许. 2   HashTable是线程安全的一个Collection. HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可

关于c#中Dictionary的使用

1.dictionary适用于唯一性的物体的,用键值对的形式将其储存:键值对的类型为泛型: 2.dictionary类似于java中的hashmap把.(我自己原先是学java的) 3.dictionary的用法:Dictionary<key,value>dic = new Dictionary<key,value>();>>>实例化一个字典 3.1:添加元素的到dictionary:dic.Add(key,value); 3.2: 查询dictionary中是否