Java中HashMap机制和原理个人总结

Java中HashMap机制和原理个人总结

原理:

  1. HashMap是以key-Value(键值)对的方式来存储数据,存储在节点中,数据类型为Node;
  2. HashMap的方法没有实现同步,所以线程是不安全的;
  3. HashMap的存储机制也是节点数组+单向链表;
  4. key不允许重复,可以理解为人的身份证,具有唯一性, key可以为null,但是只能一次,key的数据类型一般为字符串类型,便于比较,使得每个都不同;
  5. Value允许重复,相当于人的名字,可以为多个null;
  6. 一个key对应一个Value;
  7. HashMap与HashSet的最大区别就在当key一样时,新Value值会覆盖之前的key的Value;
  8. 为了方便遍历HashMap,所以在HashMap中有个entrySet用来保存HashMap的kv数据,其实是对HashMap数据的引用,并没有真正存储数据,用getKey方法调用key,用getValue方法调用Value;
  9. 在HashMap中还有专门存储key的set集合KeySet
  10. 在HashMap中有专门存储Value的集合Values
  11. HashMap中的数组数据类型是Node类并实现了Map中的Entry类,所以entrySet集合里面存储的是Entry的类型数据,将Node类包装成Entry的类型数据,但是只是引用!!!;
图示:

在这里插入图片描述

  1. 链表形成的条件:1.hash值相等;2.不是同一对象;3.key不相等;4.key不为空。
  2. HashMapNode数组第一次扩容是16个大小Node,但是有一个加载因子0.75,具有临界值(threshold)16*0.75=12,当数组存储的元素到达12个节点时,就会自动扩容table数组为原来的2倍,临界值也会跟着扩容2倍。
  3. 如果一条链表的元素超过8个且table节点数组的大小>=64个,这条链表就会进行树化,
    重点:如果一条链表元素超过8个,但是table节点数据的大小没到达64个,这时候table就会进行resize(扩容)
    例:假如table此时为16个,一条链表超过8个,并再增加一个链表元素,第一次table扩容2倍,变成32个,这时候如果再增加一个链表元素,这时候table扩容2倍,变成64个,这时候如果再增加一个链表元素,这次数组table不会再扩容,这时候这个链表就会变成红黑树(TreeNode),当这个红黑树删除节点至小于8个后,就会重新转化成链表,这个过程叫做剪枝。
链表红黑树树化过程代码举例:
public class Demo {

    public static void main(String[] args) {
        HashMap hashMap = new HashMap();


        //重复向数组中加入hash值相等,但对象不同的元素
        for (int i = 0; i <8 ; i++) {//同一节点位置形成一条8个长度的链表
            hashMap.put(new A("s"),100);
        }
        hashMap.put(new A("s"),100);//再增加同一节点,节点数组扩容至32个
        hashMap.put(new A("s"),100);//再增加同一节点,节点数组扩容至64个
        hashMap.put(new A("s"),100);//再增加同一节点,这个链表转化成红黑树!
        System.out.println(hashMap);
    }
}


class A{

    private String name;

    public A(String name) {
        this.name = name;
    }


    @Override
    public int hashCode() {
        return 100;
    }
}
  1. HashMap遍历形式举例:
public class Demo {

    @SuppressWarnings("all")
    public static void main(String[] args) {

       //定义一个Map类
        Map haMa = new HashMap();
        haMa.put("no1","ssss");
        haMa.put("no4","swx");
        haMa.put("no8","gsdsd");
        haMa.put("no13","gsds");
        haMa.put("no1222","sddsg");

        //第一种遍历:利用Map.keySet
        Set set = haMa.keySet();
        //1.增强for
        for (Object key:set) {
            System.out.println(key + "-"+haMa.get(key));
        }
        System.out.println();
        //2.迭代器
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key + "-"+haMa.get(key));
        }

        System.out.println();
        //第二种遍历:利用Map.Values
        Collection v1 = haMa.values();
        //增强for
        for (Object value:
             v1) {
            System.out.println(value);
        }
        System.out.println();
        //迭代器
        Iterator iterator1 = v1.iterator();
        while (iterator1.hasNext()) {
            Object value =  iterator1.next();
            System.out.println(value);
        }
        System.out.println();

        //第三种遍历:map.entrySet()
        Set set1 = haMa.entrySet();

        //1.增强for
        //set1里面数据类型是entry,向上转型用Object接收
        for (Object entry:set1
             ) {
            //向下转型,用Map.Entry接收,就可以使用Map.Entry里面的方法
            Map.Entry en = (Map.Entry) entry;
            System.out.println(en.getKey()+"-"+en.getValue());

        }

        System.out.println();
        //2.迭代器
        Iterator iterator2 = set1.iterator();
        while (iterator2.hasNext()) {
            Object entry =  iterator2.next();
            //向下转型,用Map.Entry接收,就可以使用Map.Entry里面的方法
            Map.Entry en = (Map.Entry) entry;
            System.out.println(en.getKey()+"-"+en.getValue());
        }



    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值