Java-集合之HashMap

HashMap简述

一种基于哈希表实现的数据类型,
在jdk1.8之前数据结构由数组+链表
在jdk1.8之后数据结构由数组+链表+红黑树。

数据安全,初始化,作用,数据顺序等

继承关系图

在这里插入图片描述

数据结构

在java中使用比较广泛用来存储相同数据类型的键值对的集合之一。在数据存储的过程中允许一个key或value为null,非线程安全且无序的集合。
在jdk1.8后,底层实现是基于数组,链表和红黑树组成的
优点: 提供高效的,删除 插入和查找操作,
缺点:线程不安全,无序

linkedHashMap 有序的HahsMap
concurrentHashMap 线程安全,通过分段锁,本质就是将整个hash表分为多个小的hash表(段),每段都能独立读写,每个段内部都是类似hashmap的实现方式,从而达到并发的效果。

是否线程安全 --否

否,在多线程环境下,数据是不同步的,如果两个线程同时操作会出现数据问题,
线程安全的map有 concurrentHashMap ,分段锁

简述new HashMap() 的流程

通过源码查看 new 的过程中,做了哪些操作,只是做了简单的初始化
通过Hashmap的无参构造初始化创建一个长度16,装载因子为0.75的map

package com.ruoyi.project.system;

import java.util.HashMap;

public class NewHashMapTest {

    public static void main(String[] args) {

        //
       HashMap<String,String> test =  new HashMap();
       
       //test.put("a","b");
       
    }

}

在这里插入图片描述

动态扩容

在put数据时 会对表的长度进行判断,当元素的数量大于装载因子乘数组的长度时,会进行扩容操作,每次扩容是原来的一倍,核心方法是resize方法。
resize方法主要是新建了一个扩容后的map,然后将原数据重新hash进集合里面,过程中数据的位置可能会有所改变,如果原来的位置已有参数,当前数据将放到链表的末尾,当链表的长度达到阈值(默认8)时,将转为红黑树。

装载因子为什么是0.75?

将空间和时间进行最合理最大程度的利用和优化。

put 流程

map.put(key,value);
例:

  • 首先获取key的hash值
  • 通过hash值扰动函数让hash更散列,其目的是为了让hash分步更均匀
  • 判断集合是否为空,为空则分配空间,
  • 构造node对象
  • 不为空则查看是否需要扩容,是否需要转红黑树
  • 通过路由算法,计算出对象存储位置计算,公式:(table.length-1) & node.hash
  • 将对象存入对应的位置中
    在这里插入图片描述

hash碰撞(冲突)

什么是hash碰撞

当A B两个不同的数据通过hash函数计算之后得到相同的值,导致B也需要放到A所在的位置,这就导致了冲突。

解决办法–四种

  • 开放定址法

     当key的hash地址p出现碰撞时,基于p再hash的到p1,如果p1仍然冲突则继续基于p,再hash ,直到得到一个不冲突的地址,将对应的数据存入。
    
  • 再hash(双hash)

     在发生冲突时,使用第二个,第三个	hash函数进行计算直到不再冲突为止	
    
  • 链地址法(hashMap默认)

     将同一个散列槽(数组的每一个槽)中的所有数据放到一个链表中,node对象有一个next对象,通过next连接起来形成链表。
    
  • 建立公共溢出区

     将hash表分为基本表和溢出表,把所有与基本表冲突的数据放入溢出区。
    

扰动函数

本质是为了让hashcode分布的更均匀
扰动函数————(h = key.hashCode()) ^ (h >>> 16) 表示:
将key的哈希code一分为二。其中:
【高半区16位】数据不变。
【低半区16位】数据与高半区16位数据进行异或操作,以此来加大低位的随机性。

  • 注意:如果key的哈希code小于等于16位,那么是没有任何影响的。只有大于16位,才会触发扰动函数的执行效果。
  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值