Java基础之:集合——Map——HashMap
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java基础之:集合——Map——HashMap,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3494字,纯文字阅读大概需要5分钟。
内容图文
Java基础之:集合——Map——HashMap
HashMap简单介绍
-
Map接口的常用实现类:HashMap、Hashtable和Properties。
-
HashMap是 Map 接口使用频率最高的实现类。
-
HashMap 是以 key-val 对的方式来存储数据 [案例 Entry ]
-
key 不能重复,但是是值可以重复,允许使用null键和null值。
-
如果添加相同的key , 则会覆盖原来的key-val ,等同于修改.(key不会替换,val会替换)
-
与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的.
-
HashMap没有实现同步,因此是线程不安全的,文档 The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.)
关于HashMap的案例,就是上一篇博客中描述Map的案例。使用的是HashMap。
HashMap底层机制
(k,v)是一个Node节点,实现了Map.Entry<K,V>。
jdk7.0的hashmap 底层实现[数组+链表], jdk8.0 底层[数组+ 链表/红黑树]
这里的链表都只有next属性,没有prev属性,即单向链表。
扩容机制
table表的扩容机制(即上图中第一行类似数组的表):
-
HashMap底层维护了Node类型的数组table,默认为null
-
当创建对象时,将加载因子(loadfactor)初始化为0.75
-
当添加元素时(调用putVal方法),需要通过该元素的哈希值获取在table中的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,需要继续判断是否相等,如果相等则直接覆盖,如果不相等则需要判断此时是树结构还是链表结构,做相应处理。如果添加时发现容量不够就需要扩容。
-
如果第一次添加,则需扩容table容量为16,临界值(threshold)为12.(16 * 0.75 = 12)
-
即当table表的内容增长到临界值(threshold)时,就会自动扩容。(添加第13个元素进入table表时,扩容)
-
如果其他次添加则需扩容table容量到原来的2倍,临界值也改为原来的两倍。(例:第2次扩容,table -> 32 , threshold -> 24)
table表中单个索引位置的扩容机制(链表/红黑树):
-
在table表中,一开始默认是长度为16的数组
-
当某一个索引中的元素超过了8时,它优先会选择将长度扩容2倍(即长度为32)的数组。
-
它会认为是不是由于数组的长度不够才导致一个索引中元素过多。
-
但当它发现长度为32时,某一个索引中的元素还是超过9时,它还是会优先选择将长度再次扩容到2倍(即长度为64)的数组。
-
在长度为64的数组中,它发现某一个索引中的元素还是超过10时,它就会对该索引所在的链表转化为红黑二叉树.
-
所以在第十一个元素时,才会对该索引所在的链表转化为红黑二叉树.
测试代码
import java.util.HashMap; public class HashMapTreeNode { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) { ? HashMap map = new HashMap(); ? for (int i = 1; i <= 20; i++) { User user = new User(); ? map.put(user, user); ? System.out.println("i =" + i); } } } ? class User { ? // 保证每个元素放入同一个索引,将hashcode设置为1 @Override public int hashCode() { return 1; } ? // 保证在同一个索引中,每个元素不会因为相同被覆盖,将equles设置为false @Override public boolean equals(Object obj) { return false; } }
?
LinkedHashMap
LinkedHashMap继承自HashMap,包含了HashMap的所有机制,但不同的是LinkedHashMap是有序的(即添加和取出顺序相同).
简单案例:
package class_HashMap; ? import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; ? public class ClassTest01_LinkedHashMap { ? @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) { ? HashMap map = new LinkedHashMap(); map.put("1", "hello01"); map.put("2", "hello02"); map.put("3", "hello03"); map.put("3", "hello05"); map.put("4", "hello02"); map.put(null, "hello02"); map.put("5", null); //遍历键值对 Set entrySet = map.entrySet(); Iterator iterator = entrySet.iterator(); while(iterator.hasNext()) { Object obj = iterator.next(); Map.Entry node = (Map.Entry)obj; System.out.println(node.getKey() + " = " + node.getValue()); } iterator = entrySet.iterator(); } ? }
程序输出:
1 = hello01
2 = hello02
3 = hello05
4 = hello02
null = hello02
5 = null
内容总结
以上是互联网集市为您收集整理的Java基础之:集合——Map——HashMap全部内容,希望文章能够帮你解决Java基础之:集合——Map——HashMap所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。