Java基础-Map-HashMap
文章目录
前言
Java中的集合类主要由Collection和Map这两个接口派生而出。
- Collection是单一数据体系
- Map是成对出现的数据体系
一、Map的HashMap实现类
数据存储是无序的,键值对中,值可以重复,键不允许
1.代码演示以及详细说明
package cn.sxau.Map;
import java.util.HashMap;
public class java_map_HashMap {
// 数据存储是无序的,键值对中,值可以重复,键不允许
//底层,数组+单向链表
public static void main(String[] args) {
/**
* 构建Map对象
* 1.无参构造方法
* 2.有参构造方法
* 3.Hash传入一个Map对象
*/
HashMap hashMap = new HashMap();
/**
* 添加数据
* 1.put(键 ,值) ,如果键相同,发生覆盖,返回被覆盖的值
* 2.putIfAbsent(键 ,值) ,如果键相同,不添加
* 3.putAll(Map map)
*/
hashMap.put("张三","1");
System.out.println(hashMap.put("张三", "2"));
System.out.println(hashMap);
/**
* 查询数据
* 1.get("键") ,得到对应的值
*/
System.out.println(hashMap.get("张三"));
/**
* 删除数据
* 1.remove("键"),传入键是因为,键是唯一性标识
* 2.remove("键","值")
* 3.clear()
*/
hashMap.remove("张三");
hashMap.clear();
/**
* 修改数据
* replace("张三","1") //传入键 ,修改值; ,如果键没有,不做任何改动
*/
hashMap.replace("张三","1");
/**
* 查看长度
* size()
*获取map集合中所有key
* keySet()
*获取map集合中所有value
* values()
* 获取键值对对象
* entrySet()
*/
hashMap.size();
}
}
二、HashMap的底层数据结构
- 1.7:HashMap的底层数据结构是数组+链表进行存储
- 1.8:HashMap的底层数据结构是数组+(链表|红黑树):当链表的长度为8,并数组容量>=64的时候变为红黑树)
- HashMap的数组初始容量为16
三、获取HashMap的键值对的索引具体操作
- 步骤一:先通过hashcode算法计算键的原始hash值,再将原始hash值再次调用HashMap中的hash方法计算二次hash值(二次计算的目的是保证索引不会越界)。
- 步骤二:将二次hash值与HashMap的初始容量进行取模,得到的数字即为键在HashMap中存储的索引下标。
四、Hash冲突产生的原因与解决办法
- 原因:Hash冲突指的是在向Hash表中存数据时,首先要用Hash函数计算出该数据要存放的地址。但是在这个地址中已经有值存在,所以这个时候就发生了Hash冲突。也就是一句话:key值不同的元素可能会映象到哈希表的同一地址上。
- 解决办法:开放定址法,再哈希法,链地址法
- 链地址法:将所有哈希地址为i的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况。
五、HashMap中链表过长解决办法
- 产生链条的原因:hash冲突(key值不同的元素可能会映象到哈希表的同一地址上)
- 解决办法:HashMap进行扩容;链条树化(当链表的长度为>=8,并数组容量>=64的时候变为红黑树)
六、HashMap扩容机制
- HashMap的初始容量为16;
- 扩容机制是:当数组中元素的数量超过3/4,每次扩容为原来的2倍,每次都是用一个新的数组替换原来的数组;重新计算原数组的所有数据并插入一个新数组。
七、HashMap的链和树相互转换
- 链——>树:链表元素超过8时数组容量>=64,会自动转化成红黑树
- 树——>链:情况一:链表元素小于等于6时(通过扩容机制),树结构还原成链表形式;情况二:remove树节点时,roor,root.left,root.right,root.left.left有一个为null,也会退化为链表
- 设置的阈值为8的原因:如果hash值足够随机,长度超过8的链表概率为亿分子6
八、HashMap对key的对象要求
- HashMap的key可以为null
- 作为key的对象,必须实现hashCode和equals,并且key的内容不可以修改