HashMap

HashMap

  • HashMap底层是哈希表数据结构

  • 哈希表是一个怎样的数据结构?

    哈希表是数组单向链表的组合体

    数组: 查询效率高,随机增删效率低

    单向链表: 查询效率低,随机增删效率高

    哈希表是将以上两种数据结构融合,充分发挥各自的优点

  • HashMap底层源代码

    public class HashMap<K,V>{
        //HashMap 底层实际上就是一个一维数组
    	transient Node<K,V>[] table;
    	//静态内部类HashMap.Node
    	static class Node<K,V> implements Map.Entry<K,V> {
            final int hash;// 哈希值(是key的hashcode()方法的执行结果,hash值通过hash算法,可以得到数组下标 )
            final K key;
            V value;
            Node<K,V> next;
        }
    }
    //哈希表:一维数组,这个一维数组里每个元素里存的是一个单向链表
    
  • V put(K key, V value)的实现原理

    第一步: 先将k 和 v 封装到Node对象里

    第二步: 底层会调用 k 的 hashCode() 方法, 获得hash值, 然后通过哈希算法, 将hash值转成数组的下标, 下标位置上如果为null, 就把Node添加到这个位置上; 如果不为null, 就会拿着k 和这个下标下的链表里的每一个k进行equals ,如果都返回null,则将Node加在这个链表的末节点, 如果其中有一个返回true,则会覆盖,这个 k 上的 v

  • V get(Object key)的实现原理

    先调用k的hashCode() 方法, 获得hash值, 然后通过哈希算法, 将hash值转成数组的下标, 下标位置上如果为null,则返回null; 如果不为null, 就会拿着k 和这个下标下的链表里的每一个k进行equals ,如果都返回null,则返回null; 如果其中有一个返回true,则返回这个k 上的 v

  • HashMap集合key部分的特点:

    无序,不可重复

    为什么无序? 因为不知道挂到哪个链表上

    怎么保证不可重复:? equals方法保证HashMap的key不可重复,如果key重复,value会被覆盖

  • 注意: 同一个单向链表上的所有节点的hash值相同

  • 哈希表使用不当时无法发挥性能

    假设将所有的hashCode() 返回值固定为某个值,那么会导致哈希表底层变成了纯单向链表. 这种情况我们成为 : 散列分布不均匀

    假设所有的hashCode()的返回值都不一样,那么会导致哈希表底层变成了一维数组,这种情况也是 散列分布不均匀

  • 重点 : 放在HashMap 集合key部分的元素,需要同时重写equals和hashCode 方法

    没重写equals方法,会导致可以存入相同内容的key

    没重写hashCode 方法,会导致hash值都不一样,那么会导致哈希表底层变成了一维数组

  • HashMap集合的默认初始化容量是16,默认加载因子是0.75

    默认加载因子 : 当HashMap容量达到75%时会进行扩容,扩容后容量时原容量的2倍

    重点 : HashMap的初始化容量必须是2的倍数,这也是官方推荐的

    这是为了达到散列分布均匀, 使HashMap的存储效率提高

  • 在jdk8以后,如果哈希表里的单向链表里的元素超过8个,那么这个单向链表的数据结构会转换成红黑树数据结构; 当红黑树节点的数少于6个时,那么红黑树会转换成单向链表

  • hash值相同的节点一定在同一链表下,hash值不同的节点可能在同一链表下,这现象叫"哈希碰撞"

  • HashMap的key值允许为null,但最多只能有一个

  • HashTable的key和value均不能为null

posted @ 2020-12-13 23:01  阿灿呀  阅读(112)  评论(0)    收藏  举报