JAVA集合之HashMap

  1. HashMap底层是数组+链表+红黑树,HashSet底层即是HashMap,在前面《JAVA集合之HashSet》已记录过,故此只做一些分析。
  2. 调用HashMap()的无参构造方法时,会初始化加载因子,并且此时table数组是null。
    public HashMap() {
        this.loadFactor = 0.75F;
    }
  1. 当第一次向HashMap中添加元素时,会扩容到16,元素会存放在HashMap$Node对象中。我们知道HashMap是K-V的形式,其实最终集合里面的元素是放在Entry<K,V>中的,其中,K是放在set集合中,V是放在connection集合中。因为Entry对象有getKey()和getValue()方法,所以放在Entry中只是为了方便遍历。但是真正的数据其实还在Node对象里,Entry只是一个引用。
  • Node对象实现了Entry对象
    static class Node<K, V> implements Entry<K, V> {
  • 代码验证K存放于set集合,V存放于connection集合
    public static void main(String[] args) {
        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put("a","aa");
        hashMap.put("b","bb");
        hashMap.put("c","cc");
        Set<Object> keySet = hashMap.keySet();
        Collection<Object> values = hashMap.values();
    }
  1. HashSet跟hashMap由于底层一致,所以可以总结出一些互推的关系
  • HashSet集合里的值与HashMap集合的key值都不能重复,原因很简单,都是因为底层源码中的key是不允许重复的,HashSet的值是存放在key中,value只是存放了一个公用的new Object()对象占位。
  • HashSet集合里的值与HashMap集合的key值都可以为null,但是只能有一个。并且存放顺序和取出顺序不一致,那当HashMap的key为null时,这对<K,V>是不是也会放在第一位(分析见前文《JAVA集合之HashSet》)。
  • HashMap集合的value可以为null,可以重复,底层源码并没有对其进行限制。
  • 扩容机制前文也提到过,这里也不赘述。有一点需要提一下,大家熟知的哈希冲突就是通过key进行哈希运算得到了一个下标值,并且在这个下标值的table数组上已经存放了其他元素。HashMap的解决方法是将新加的元素添加到该下标Node对象的后面形成链表,俗称拉链法。下图补充计划hash值和下标值的源码:
    hash值
    static final int hash(Object var0) {
        int var1;
        return var0 == null ? 0 : (var1 = var0.hashCode()) ^ var1 >>> 16;
    }

下标值(var9即下标值,var8是第一次扩容table长度16,var1是前面计算出来的hash值)

    final V putVal(int var1, K var2, V var3, boolean var4, boolean var5) {
        HashMap.Node[] var6;
        int var8;
        if ((var6 = this.table) == null || (var8 = var6.length) == 0) {
            var8 = (var6 = this.resize()).length;
        }

        Object var7;
        int var9;
        if ((var7 = var6[var9 = var8 - 1 & var1]) == null) {
            var6[var9] = this.newNode(var1, var2, var3, (HashMap.Node)null);
        } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值