码迷,mamicode.com
首页 > 编程语言 > 详细

Java技术之HashMap

时间:2014-07-30 20:37:44      阅读:304      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   java   strong   数据   for   

     哈希映像,它在Java中经常用到,主要保存key-value数据,其中HashMap实现了Map接口。系统通过Hash算法来计算key-value存储的位置,这样可以快速存取Map的key-value对。

HashMap的存储实现

HashMap采用一种所谓的“Hash 算法”来决定每个元素的存储位置。下面结合源码解析HashMap的实现。

HashMap<String, String> map=new HashMap<String, String>();
map.put("A", "Forsta");
map.put("B", "Sam");
map.put("C", "Jack");

HashMap通过put方法将key-value保存到hashmap中。

 1  public V put(K key, V value) {
 2         if (key == null)
 3             return putForNullKey(value);
 4         int hash = hash(key.hashCode());
 5         int i = indexFor(hash, table.length);
 6         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
 7             Object k;
 8             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
 9                 V oldValue = e.value;
10                 e.value = value;
11                 e.recordAccess(this);
12                 return oldValue;
13             }
14         }
15 
16         modCount++;
17         addEntry(hash, key, value, i);
18         return null;
19     }

保存key-value具体的流程是,首先获取到key,判断key是否为null,如果为null,则直接将value保存到key=null处。如果所求key关键字已经存储在Hash表中,则覆盖当前位置。如果没有保存就直接添加一个Entry,插入表中。新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部。

否则首先计算key的hash值  获取key对象的hashCode---Hash算法---求得表索引值。

1  static int hash(int h) {
2         h ^= (h >>> 20) ^ (h >>> 12);
3         return h ^ (h >>> 7) ^ (h >>> 4);
4     }
1  static int indexFor(int h, int length) {
2         return h & (length-1);
3     }

这个方法非常巧妙,它总是通过 h &(table.length -1) 来得到该对象的保存位置。table.length-1保证返回索引小于表长,一定位于表中。

1 void addEntry(int hash, K key, V value, int bucketIndex) {
2         Entry<K,V> e = table[bucketIndex];
3         table[bucketIndex] = new Entry<>(hash, key, value, e);
4         if (size++ >= threshold)
5             resize(2 * table.length);
6     }

addEntry方法,将新插入的Entry放到数组表中,如果之前表中已经有Entry数据了,则将新添加的Entry对象next指向原来的对象,形成Entry链;如果没有,则指向空。

如果数据超过threshold值,则进行扩容,但每次都原来的2倍。

HashMap具体的结构如下图

bubuko.com,布布扣

HashMap 的读取实现 

     当 HashMap 的每个 bucket 里存储的 Entry 只是单个 Entry ——也就是没有通过指针产生 Entry 链时,此时的 HashMap 具有最好的性能:当程序通过 key 取出对应 value 时,系统只要先计算出该 key 的 hashCode() 返回值,在根据该 hashCode 返回值找出该 key 在 table 数组中的索引,然后取出该索引处的 Entry,最后返回该 key 对应的 value 即可。看 HashMap 类的 get(K key) 方法代码: 

 1  public V get(Object key) {
 2         if (key == null)
 3             return getForNullKey();
 4         int hash = hash(key.hashCode());
 5         for (Entry<K,V> e = table[indexFor(hash, table.length)];
 6              e != null;
 7              e = e.next) {
 8             Object k;
 9             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
10                 return e.value;
11         }
12         return null;
13     }

 

Java技术之HashMap,布布扣,bubuko.com

Java技术之HashMap

标签:style   blog   http   color   java   strong   数据   for   

原文地址:http://www.cnblogs.com/forsta/p/3878809.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!