HashMap(jdk1.8)
来源:互联网 发布:godaddy域名续费好贵 编辑:程序博客网 时间:2024/06/07 16:33
1.类声明:
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {}
2.变量:
//默认初始化容量 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 //最大容量 static final int MAXIMUM_CAPACITY = 1 << 30; //默认加载因子 static final float DEFAULT_LOAD_FACTOR = 0.75f; //对于table里面的每个列表,从链表结构转为红黑树结构的阈值 static final int TREEIFY_THRESHOLD = 8; //对于table里面的每个列表,从红黑树结构转为列表结构的阈值 static final int UNTREEIFY_THRESHOLD = 6; //最小树化容量。只有当表的容量达到这个阈值,才能从列表结构转为树结构 static final int MIN_TREEIFY_CAPACITY = 64; //当改变了表的映射数目(put方法增加了新的Node节点)或者修改了表结构(remove(),clear())的时候,进行+1,若是对map进行迭代的时候,发生modCount不是期望的modCount,即被修改了,则抛出ConcurrentModificationException异常 transient int modCount;
3.方法:
//找到不小于cap的最小的2的n次方,这个算法之精辟令人叹为观止。具体可见参考文章1。通过右移使得cap-1表示的二进制数每一位都变成1。最后加1得到所需数。 static final int tableSizeFor(int cap) { int n = cap - 1; n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; } //put方法 public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } //若onlyIfAbsent为true,不会覆盖掉旧值,若为false,会覆盖掉旧值 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode)//如果是TreeNode节点 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else {//如果是链表节点 for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null);//往链表尾部插入节点,jdk7是往链表头部插入节点。 //当链表数量大于树化阈值时,进行树化操作,对应的当remove的时候会有一个链表化的操作 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } //如果找到了旧的数据,则根据onlyIfAbsent值决定是否更新 if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount;//当增加了新的node时,修改次数+1 if (++size > threshold) resize(); afterNodeInsertion(evict); return null; } //往树结构中插入数据 final TreeNode<K,V> putTreeVal(HashMap<K,V> map, Node<K,V>[] tab, int h, K k, V v) { Class<?> kc = null; boolean searched = false; TreeNode<K,V> root = (parent != null) ? root() : this; for (TreeNode<K,V> p = root;;) { int dir, ph; K pk; if ((ph = p.hash) > h) dir = -1; else if (ph < h) dir = 1; else if ((pk = p.key) == k || (k != null && k.equals(pk))) return p; else if ((kc == null && (kc = comparableClassFor(k)) == null) || (dir = compareComparables(kc, k, pk)) == 0) { if (!searched) { TreeNode<K,V> q, ch; searched = true; if (((ch = p.left) != null && (q = ch.find(h, k, kc)) != null) || ((ch = p.right) != null && (q = ch.find(h, k, kc)) != null)) return q; } dir = tieBreakOrder(k, pk); } TreeNode<K,V> xp = p; if ((p = (dir <= 0) ? p.left : p.right) == null) { Node<K,V> xpn = xp.next; TreeNode<K,V> x = map.newTreeNode(h, k, v, xpn); if (dir <= 0) xp.left = x; else xp.right = x; xp.next = x; x.parent = x.prev = xp; if (xpn != null) ((TreeNode<K,V>)xpn).prev = x; moveRootToFront(tab, balanceInsertion(root, x)); return null; } } }
参考文章:1.http://blog.csdn.net/fan2012huan/article/details/51097331
2.http://blog.csdn.net/crazy1235/article/details/75579654
阅读全文
0 0
- jdk1.8 hashmap
- 数据结构--jdk1.8 HashMap
- HashMap(JDK1.8)
- HashMap(jdk1.8)
- JDK1.8 HashMap
- Jdk1.8 HashMap解读
- jdk1.8 HashMap简介翻译
- jdk1.8 HashMap性能提升
- JDK1.8 HashMap源码分析
- JDK1.8 HashMap源码分析
- 【jdk1.8】HashMap源码分析
- HashMap(JDK1.8)源码剖析
- JDK1.8 HashMap 深入理解
- jdk1.8 hashMap源码分析
- JDK1.8 HashMap 源码分析
- JDK1.8 HashMap源码分析
- HashMap 源码解析(JDK1.8)
- HashMap的jdk1.8分析
- 如何判断对象是否存在
- Android开发--使用实体类解析JSON文本
- find命令;selinux防火墙
- 1-7监控和管理linux进程
- java入门基础
- HashMap(jdk1.8)
- java 编写程序实现从控制台接收一个 5 位以上的整数,使用数组来判断该数字 * 是否是回文数。(例如:789987,12344321是回文数)
- ThinkPHP权限认证Auth实例详解
- Linux的Socket编程
- asasasa
- activiti学习笔记(四) 配置器
- 8.6 二叉树----基本操作
- 【OpenCv应用笔记】基于OpenCv的视频截图C++程序
- Struts2的系统架构