Hash结构
关于HashMap 在http://www.iteye.com/topic/754887这篇文章中有做比较好的讲解
下面是我在一些点上自己的看法。
我们会经常使用HashMap类来进行存储数据,HashMap<K k,V v>map = new HashMap<K k,V v>();对于Map我们经常使用的也就是put(k,v);remove();search();这三个方法,我们添加数据到HashMap结构中,只觉得它用起来还不错,但它不错在哪?
一,Hash结构有什么优势?
我们知道数组是便于查找,因为它的下标,而链表便于添加和删除,(修改地址指向),但是对于很多个数,比如上亿,如果我们用数组来存储这么多数,如果我们要删除其中的一个元素,我们将会移动N个,同样用在链表查找的时候也很费劲。Hash结构中的拉链式(书上的名词)是结合数组和链表的一种存储结构(还有一种叫开放定址法)通过数组的下标设成Index索引,把结点挂在数组Entry[]上,Hash结构的优势在于它既便于查找,也在删除和添加上较快。
二,我对HashMap的浅析
1)
static class Entry<K,V> implements Map.Entry<K,V> { final K key;//关键字 V value;//存储的数据数值 Entry<K,V> next;//在解决冲突的时候,创建链表的时候使用,表示下一个结点。 final int hash; HashMap用Entry类来存储数据,HashMap中数组的默认长度是16 static int hash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }int hash = hash(k.hashCode());int i = indexFor(hash, table.length);
static int indexFor(int h, int length) { return h & (length-1); }Entry<k,v>node = new node<k,v>();index=Indexfo(hash,table.length);node.next=table[index].next;table[index].next =node;
resize(int newCapacity){...transfer(newTable);//转移原数组的元素到新的数组...}void transfer(Entry[] newTable) { Entry[] src = table; int newCapacity = newTable.length; for (int j = 0; j < src.length; j++) { Entry<K,V> e = src[j]; if (e != null) { src[j] = null; do { Entry<K,V> next = e.next; int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } while (e != null); } } }threshold = (int)(newCapacity * loadFactor);这个就是设置阀值 在HashMap中loadFactor 的取值是0.75,官方给出了一个取值范围0.6~0.9 这样的效果是比较好的,到底好在哪里?我测试不出,如果你们有兴趣,可以自己想个方法测试一下,前提,你的电脑性能要好。