day-2-4-3

哈希表

Hash一般翻译为散列,也有直接音译为哈希的,这就是把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值(哈希值);这种转换是一种压缩映射,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值

简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

消息摘要算法的使用 md5、SHA-1等

MessageDigest md = MessageDigest.getInstance("md5");
String source="柏嘉safsadfsadflsajdflsakdvklxjcvlkjdsl";
String ss=Base64.getEncoder().encodeToString(sbyte);
System.out.println(ss);

所有散列函数都有如下一个基本特性:根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。但是,根据同一散列函数计算出的散列值如果相同,输入值不一定相同。

哈希冲突

当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,就把它叫做碰撞(哈希碰撞)。哈希碰撞的解决方案为开放地址法和链地址法。

以key/value的方式存储数据,采用拉链法综合了数组和链表结构。如果key已知则存取效率较高,但是删除慢,如果不知道key存取则慢,对存储空间使用不充分。最典型的实现是HashMap。

JDK8+对桶内数据处理从链表转换为红黑树,则查询效率从O(N)提高到O(logN)。当链表中的个数超过8个时会转换为红黑树

Map实现类

HashMap、TreeMap、LinkedHashMap、Hashtable等

HashMap
类定义

public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable

注意:Map接口的定义

public interface Map<K, V> 没有父接口

具体的内部数据存储方式
  • transient Node<K,V>[] table;

    哈希表的本质是一个数组,数组中每一个元素称为一个桶,桶中存放的是键值对

  • transient Set<Map.Entry<K,V>> entrySet;

    并不是用于实际存储数据,主要用于针对entrySet和keySet两个视图提供支持

  • transient int size;

    当前集合中的元素个数

  • final float loadFactor;

    当前集合的负载因子,当前Map集合中扩容的阈值【负载因子*最大容积】

  • transient int modCount;

    修改次数,主要用于实现多线程操作时的快死异常

重要的阈值
  • static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;

    aka 16 默认的初始化容积

  • static final int MAXIMUM_CAPACITY = 1 << 30;

    最大容积值,实际上就是2的30次方

  • static final float DEFAULT_LOAD_FACTOR = 0.75f;

    默认的负载因子/加载因子

  • static final int TREEIFY_THRESHOLD = 8;

    树化阈值:即链表转成红黑树的阈值,在存储数据时,当链表长度 > 该值时,则将链表转换成红黑树

  • static final int MIN_TREEIFY_CAPACITY = 64;

    最小树形化容量阈值:即 当哈希表中的容量 > 该值时,才允许树形化链表 (即将链表转换成红黑树)否则,若桶内元素太多时,则直接扩容,而不是树形化

  • static final int UNTREEIFY_THRESHOLD = 6;

    桶的链表还原阈值:即红黑树转为链表的阈值,当在扩容resize)时(此时HashMap的数据存储位置会重新计算),在重新计算存储位置后,当原有的红黑树内数量 < 6时,则将红黑树转换成链表

内部存储的实现

静态内部类用于实现Entry,HahMap中存放的key/value对就被封装为Node对象。其中key就是存放的键值,用于决定具体的存放位置;value是具体存放的数据,hash就是当前Node对象的hash值,next用于指向下一个Node节点(单向链表)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值