2020年12月26日星期六

Java基础之:集合——Map——HashMap

Java基础之:集合——Map——HashMap

HashMap简单介绍

  1. Map接口的常用实现类:HashMap、Hashtable和Properties。

  2. HashMap是 Map 接口使用频率最高的实现类。

  3. HashMap 是以 key-val 对的方式来存储数据 [案例 Entry ]

  4. key 不能重复,但是是值可以重复,允许使用null键和null值。

  5. 如果添加相同的key , 则会覆盖原来的key-val ,等同于修改.(key不会替换,val会替换)

  6. 与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的.

  7. 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表的扩容机制(即上图中第一行类似数组的表):

  1. HashMap底层维护了Node类型的数组table,默认为null

  2. 当创建对象时,将加载因子(loadfactor)初始化为0.75

  3. 当添加元素时(调用putVal方法),需要通过该元素的哈希值获取在table中的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,需要继续判断是否相等,如果相等则直接覆盖,如果不相等则需要判断此时是树结构还是链表结构,做相应处理。如果添加时发现容量不够就需要扩容。

  4. 如果第一次添加,则需扩容table容量为16,临界值(threshold)为12.(16 * 0.75 = 12)

  5. 即当table表的内容增长到临界值(threshold)时,就会自动扩容。(添加第13个元素进入table表时,扩容)

  6. 如果其他次添加则需扩容table容量到原来的2倍,临界值也改为原来的两倍。(例:第2次扩容,table -> 32 , threshold -> 24)

table表中单个索引位置的扩容机制(链表/红黑树):

  1. 在table表中,一开始默认是长度为16的数组

  2. 当某一个索引中的元素超过了8时,它优先会选择将长度扩容2倍(即长度为32)的数组。

  3. 它会认为是不是由于数组的长度不够才导致一个索引中元素过多。

  4. 但当它发现长度为32时,某一个索引中的元素还是超过9时,它还是会优先选择将长度再次扩容到2倍(即长度为64)的数组。

  5. 在长度为64的数组中,它发现某一个索引中的元素还是超过10时,它就会对该索引所在的链表转化为红黑二叉树.

  6. 所以在第十一个元素时,才会对该索引所在的链表转化为红黑二叉树.

测试代码

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

 









原文转载:http://www.shaoqun.com/a/504124.html

跨境电商:https://www.ikjzd.com/

联动优势电子商务:https://www.ikjzd.com/w/1921

new old stock:https://www.ikjzd.com/w/2341


Java基础之:集合——Map——HashMapHashMap简单介绍Map接口的常用实现类:HashMap、Hashtable和Properties。HashMap是Map接口使用频率最高的实现类。HashMap是以key-val对的方式来存储数据[案例Entry]key不能重复,但是是值可以重复,允许使用null键和null值。如果添加相同的key,则会覆盖原来的key-val,等同于修改.(
二类电商:二类电商
auditor:auditor
2020年清明节放假几天?清明节怎么放假?:2020年清明节放假几天?清明节怎么放假?
贵州有什么好吃的,贵州有哪些美食,贵州美食攻略:贵州有什么好吃的,贵州有哪些美食,贵州美食攻略
海洋国际海外仓(Ocean Int Ltd):海洋国际海外仓(Ocean Int Ltd)

没有评论:

发表评论