一步一步解析java集合框架HashMap源码(1)
来源:互联网 发布:vb自学网站 编辑:程序博客网 时间:2024/05/10 23:28
首先看如何简单实用HashMap
public static void main(String[] args) { Map<String,String> map=new HashMap<String,String>(); map.put("firstKey","firstValue"); map.put("secondKey","secondValue"); }
- 首先查看HashMap的属性
/** * 默认的初始化容量16 */ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 乘以16(2的4次方) /** * 最大容量 */ static final int MAXIMUM_CAPACITY = 1 << 30; /** * 加载因子 */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** * 散列表的加载因子 */ final float loadFactor; /** * 存储键值对集合Node<K,V>数组 */ transient Node<K,V>[] table; /** * 键值对数 */ transient int size;
- 默认构造函数
public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; }
- 添加数据
/** * 添加键值对 */ public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
/** * 获取hash值 */ static final int hash(Object key) { int h; //通过运算符计算得到一个hash值 return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
这里调用了Object的hashCode()方法,只是个原生函数,java自身并没有实现,由C++语言进行实现,java只管调用。
public native int hashCode();
/** * @param hash hash值 * @param key 键 * @param value 值 */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; //默认构造函数,table==null if ((tab = table) == null || (n = tab.length) == 0) //resize();初始化散列表table n = (tab = resize()).length;//16 //(n - 1) & hash计算索引 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) 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); 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; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }//没有实体,空的函数 void afterNodeInsertion(boolean evict) { }
关注下面两点:
public static void main(String[] args) { Map<String,String> map=new HashMap<String,String>(); map.put("firstKey","firstValue"); map.put("secondKey","secondValue"); String first="firstKey"; String second="secondKey"; System.out.println(hash(first));//-549860682 System.out.println(hash(second));//-817573361 System.out.println(getIndex(hash(first)));//6 System.out.println(getIndex(hash(second)));//15 } static int getIndex(int hash){ return 15&hash; } static final int hash(Object key) { int h; //通过运算符计算得到一个hash值 return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
第一次添加数据map.put(“firstKey”,”firstValue”);
需要resize();初始化table为容量16的数组;table[6]=new Node(…)
第二次添加数据不需要resize();table[15]=new Node(…);
public static void main(String[] args) { Map<String,String> map=new HashMap<String,String>(); map.put("firstKey","firstValue"); map.put("secondKey","secondValue"); map.put("fir","thirdValue"); map.put("first","fourthValue"); String first="firstKey"; String second="secondKey"; String third="fir"; String fourth="first"; System.out.println(hash(first));//-549860682 System.out.println(hash(second));//-817573361 System.out.println(hash(third));//101390 System.out.println(hash(fourth));//97441662 System.out.println(getIndex(hash(first)));//6 System.out.println(getIndex(hash(second)));//15 System.out.println(getIndex(hash(third)));//14 System.out.println(getIndex(hash(fourth)));//14 }
添加了相同索引的数据
/** * @param hash hash值 * @param key 键 * @param value 值 */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; //默认构造函数,table==null if ((tab = table) == null || (n = tab.length) == 0) //resize();初始化散列表table n = (tab = resize()).length;//16 //(n - 1) & hash计算索引 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)//false e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount ) { if ((e = p.next) == null) { //以链表形式添加进散列表,构造新节点指定next **p.next = newNode(hash, key, value, null);** if (binCount >= TREEIFY_THRESHOLD - 1) //TREEIFY_THRESHOLD=8 treeifyBin(tab, hash); break;//跳出整个循环 } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; //第一次添加数据,threshold=12, if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
0 0
- 一步一步解析java集合框架HashMap源码(1)
- 一步一步解析java集合框架HashMap源码(1)
- 一步一步解析java集合框架HashMap源码(2)
- 一步一步解析java集合框架HashMap源码(3)
- 一步一步解析java集合框架LinkedList源码(3)
- Java集合框架之HashMap源码解析
- 一步一步解析集合框架LinkedList源码(1)
- Java集合框架--HashMap源码解析(JDK1.7)
- HashMap-Java集合框架之 Java HashMap 源码解析
- Java集合框架之 Java HashMap 源码解析
- 一步一步解析集合框架ArrayList源码(2)
- 一步一步解析集合框架ArrayList源码(3)
- 一步一步解析集合框架ArrayList源码(4)
- 一步一步解析集合框架LinkedList源码(2)
- 一步一步解析集合框架LinkedList源码(4)
- 一步一步解析集合框架ArrayList源码
- 《Java源码解析》集合框架Map之HashMap
- 【java集合】HashMap源码解析
- gradle构建项目之java插件
- CAS4.2.4 连接Liferay6.2以上版本数据库用户表验证用户
- SVN中的hooks
- Java中Json构造和解析
- 网易2017校园招聘数据挖掘笔试题编程题 分田地
- 一步一步解析java集合框架HashMap源码(1)
- HDU 5615 Jam's math problem(水~)
- 数据库备份
- set容器
- isa指针的理解
- 未能同步iphone 因为这台电脑不再授权使用在此iPhone上购买的项目
- robocode机器人1.0版
- Sqldbx连接OracleX64位
- 不可以!