Java HashMap与散列
来源:互联网 发布:淘宝上怎么做网拍模特 编辑:程序博客网 时间:2024/05/20 14:15
HashMap内部存储和查找采用的是散列法。
先看HashMap的默认构造函数:
public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR;//默认的装填因子0.75 threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); table = new Entry[DEFAULT_INITIAL_CAPACITY];//默认的初始数组长度为16 init(); }
里面定义了一个哈希表table,哈希表里放的元素是Entry,Entry里定义了如下成员变量:
final K key;V value;Entry<K,V> next;value是具体的数据元素,key是value的关键字。然后定义了自身类型的变量,所以这是一个自引用类,由此可知,HashMap解决哈希冲突采用的是方法是开散列法,也就是链表法。
接着看存储方法,也就是 put方法:
public V put(K key, V value) { if (key == null) return putForNullKey(value);//有一个专门存放key为null的方法 int hash = hash(key.hashCode()); 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;}从key到最后的哈希值(索引),调用了3个方法:
1.key.hashCode()(如果没重写Object的hashCode方法,返回的就是该对象的内部地址转换成的一个整数,这也是为什么Java需要为Object类定义hashCode方法,这是一个本地方法)
2.HashMap.hash()
static int hash(int h) { // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4);}
3.HashMap.indexFor()
/** * Returns index for hash code h. */ static int indexFor(int h, int length) { return h & (length-1); }
for循环判断是否已放入该元素,然后是核心的添加元素的方法addEntry:
void addEntry(int hash, K key, V value, int bucketIndex) {Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = new Entry<K,V>(hash, key, value, e); if (size++ >= threshold) resize(2 * table.length);//哈希表扩容}先取出原来的元素,然后放入新添加的元素。看一下Entry的构造方法:
Entry(int h, K k, V v, Entry<K,V> n) { value = v; next = n; key = k; hash = h;}这里把新添加的元素指向了原来的元素,于是我们知道,越早放入的元素,离table就越远。
到此,元素的存储基本结束。另外附上HashMap的内存结构图:
检索的方法就不多说了,怎么存就怎么取,代码如下:
public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }
0 0
- Java HashMap与散列
- java 散列与散列码探讨 ,简单HashMap实现散列映射表执行各种操作示列
- java HashMap:散列映射表
- HashMap散列映射表
- java IdentityHashMap 与HashMap
- 散列与Java Map结构分析
- Java基础-理解散列与散列码
- Java的集合与散列
- java的HashMap与ConcurrentHashMap
- Java 中的 TreeMap 与 HashMap
- java中的HashMap与HashTable
- java基础---HashMap与HashTable
- java基础---HashMap与HashTable
- java的HashMap与ConcurrentHashMap
- [java]HashMap与Bean互转
- Java - Hash - HashMap与HashTable
- Java中TreeMap()与HashMap()
- java集合-hashMap与TreeMap
- 上班语录 2014-01-26
- Fibonacci数
- Qt图片显示效率的比较
- CC+语言 struct 深层探索——CC + language struct deep exploration
- xmpp即时通讯四
- Java HashMap与散列
- Hibernate中所有包作用详细讲解
- windows8系统令人狂抓的问题,以及解决对策
- 深度拷贝指定扩展名文件
- Sublime Text 2 快捷键用法大全
- android 常用到的 listview ,scrollview 等上拉刷新
- Pat(Basic Level)Practice--1006(换个格式输出整数)
- 最好用图像处理库CxImage入门
- jquery 中文api