Java-HashMap详解
来源:互联网 发布:七月算法 邹博退出 编辑:程序博客网 时间:2024/05/21 01:47
jdk 1.7
基础知识:Object下的hashcode()方法和equals()方法
HashMap是线程不安全的,可以说是HashTable的轻量级实现
底层实现是数组+链表,即Entry[]
Entry为桶,有next方法指向桶中下一个元素
初始大小(Capacity)为16 注意:1.大小为2的N次幂,2.大小指的是HashMap中Entry的个数
初始因子(Factor)0.75
阀值=Capacity*Factor
一旦大小(size)超过阀值,会扩充HashMap,扩充至当前大小的2倍
可以自定义初始大小(会设置成大于var1、且是2的N次幂的数中最小的那个)
public HashMap(int var1) { this(var1, 0.75F); }
也可以自定义因子
public HashMap(int var1, float var2) { if(var1 < 0) { throw new IllegalArgumentException("Illegal initial capacity: " + var1); } else { if(var1 > 1073741824) { var1 = 1073741824; } if(var2 > 0.0F && !Float.isNaN(var2)) { this.loadFactor = var2; this.threshold = tableSizeFor(var1); } else { throw new IllegalArgumentException("Illegal load factor: " + var2); } } }
put操作
public V put(K key, V value) { // 1.对key为null的操作(会放在下标为0的位置上) if (key == null) return putForNullKey(value); // 2.计算key对应的hash值 int hash = hash(key.hashCode()); // 3.i为当前hash值在数组中的位置(其值为hash&(table.length - 1)) int i = indexFor(hash, table.length);<pre name="code" class="java"> // 4.如果数组该位置有Entry,则进入循环for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k; // 5.判断:查找Entry<Key,Value>链表中是否已经有了以key值为Key存储的Entry<Key,Value>对象,<pre class="brush:java; toolbar: true; auto-links: false;"> //已经存在,则将Value值覆盖到对应的Entry<Key,Value>对象节点上if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } // 6.该位置为空 或者 Entry中不存在该key,则新建Entry,插入到这个桶的头部 modCount++; addEntry(hash, key, value, i); return null; }
get操作
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; }
HashMap性能的提高即修改初始大小以及因子
如果确定会容纳多少个Entry,可以直接将初始大小设置成该数。
如果Entry会特别多,尽量将Factor设置得大些,避免Entry[]利用率不高。
因为扩容的时候,会新建一个Entry[],并将之前的Entry[]中的元素全部重新hash一次,然后加入新的数组,可以看出代价特别大,所以初始大小的选择很重要。
java8中对HashMap作了性能优化,将以前的数组+链表改为了数组+链表/树,为了避免一个链表太长的问题。
修改之后,过长的链表会被转化为树,则HashMap的最坏检索时间复杂度从O(n)降到了O(logn)。
0 0
- Java中的HashMap详解
- java中HashMap详解
- Java HashMap实现详解
- java中HashMap详解
- java中HashMap详解
- java中HashMap详解
- java中HashMap详解
- JAVA hashmap详解
- java中hashMap详解
- java中HashMap详解
- Java HashMap实现详解
- Java HashMap实现详解
- Java HashMap实现详解
- Java HashMap实现详解
- Java HashMap实现详解
- java中HashMap详解
- java中HashMap详解
- java中HashMap详解
- HDU 1059 Dividing
- neural-networks-and-deep-learning false_minimum.py
- 剑指offer——左旋转字符串
- nodejs代码封装基础
- ROS学习之带有用户自定义参数的回调函数
- Java-HashMap详解
- POJ2366
- python文件转换为exe可执行文件的方法
- Linux-tail命令使用方法演示例子
- 在MAC下配置mysql 5.6.31 及以上的 数据库的默认编码问题
- 换行符
- WinDbg配置和使用基础
- POJ 3150 循环矩阵的应用
- 插入flash的简单代码