HashMap基础的学习
来源:互联网 发布:nat123免费域名 编辑:程序博客网 时间:2024/06/06 03:11
loadFactor:加载因子其实是空间与时间的一种平衡关系,加载因子小了,空间浪费多,但是可以减少hash冲突,加载因子大了,节省空间的同时也加大了hash冲突的风险,造成查询慢。
modCount:操作计数,应该是用来迭代的时候判断是否并发了
threshold:map长度与扩展因子的乘积,超过这个值就需要扩容了
hashmap默认为16长度,长度为2的次方,比如new hashmap(17),那么长度实际为32
hashmap实例化的时候并不会分配数组空间,而是在put的时候才会
null的key的hash为0
hashmap几个关键的方法
1.put
public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); //通过key算出hash值 int hash = hash(key); //通过hash值算出数组下表 int i = indexFor(hash, table.length);//遍历链表--key有对应的value返回老值 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; }
void addEntry(int hash, K key, V value, int bucketIndex) {//size超过了threshold需要扩容 *2 if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); }//添加entry createEntry(hash, key, value, bucketIndex); }void createEntry(int hash, K key, V value, int bucketIndex) {//将新加的entry放进数组位置,next指向之前的entry Entry<K,V> e = table[bucketIndex]; table[bucketIndex] = new Entry<>(hash, key, value, e); size++; }//扩容 遍历hash数组上的entry链表全部重新放置进新的map,耗时,所以尽量避免扩容 void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length; for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> next = e.next; if (rehash) { e.hash = null == e.key ? 0 : hash(e.key); } int i = indexFor(e.hash, newCapacity); e.next = newTable[i]; newTable[i] = e; e = next; } } }
2.remove
public V remove(Object key) { Entry<K,V> e = removeEntryForKey(key); return (e == null ? null : e.value); }final Entry<K,V> removeEntryForKey(Object key) { if (size == 0) { return null; } int hash = (key == null) ? 0 : hash(key);//通过key找到hash数组的位置 int i = indexFor(hash, table.length); Entry<K,V> prev = table[i]; Entry<K,V> e = prev; while (e != null) { Entry<K,V> next = e.next; Object k;//找到key了 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { modCount++; size--;//如果是第一个entry就是目标entry if (prev == e) table[i] = next; else//当前的entry就是需要remove的,只要将上一个的NEXT指向下一个就可以了 prev.next = next; e.recordRemoval(this); return e; }//没有找到entry,下一个 此时prev代表上一个,e代表当前的,next代表下一个 prev = e; e = next; } return e; }
阅读全文
0 0
- HashMap基础的学习
- Java基础学习1--HashMap
- HashMap的学习感悟
- HashMap的学习
- hashmap的一点学习
- HashMap的学习笔记
- HashMap的遍历(学习)
- HashMap的底层学习
- 【JAVA基础】HashMap的遍历
- HashMap基础
- 集合类的学习--HashMap
- HashMap的学习(一)
- 关于hashMap的源码学习
- Java基础---hashmap的实现原理
- Java基础-hashMap的相关问题
- Java基础-hashMap的相关问题
- java核心基础--jdk源码分析学习--HashMap
- HashMap学习
- 39. Combination Sum
- flask转换器
- 最长上升子序列(LIS)和最长下降子序列(LDS)
- 抽象类(abstract class)和接口(interface)有什么异同?
- linux 下 du, df, top, free, pstack, su, sudo(sudo -, sudo -s), adduser, password命令介绍
- HashMap基础的学习
- 线性代数与高等代数——学习资料(更新..........)
- OpenStack公共组件oslo之十二——oslo.policy
- 使用anaconda搭建TensorFlow环境
- 静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?
- 714. Best Time to Buy and Sell Stock with Transaction Fee
- C语言指针 易错知识
- 函数作用域
- java数据类型和变量