HashMap、LinkedHashMap、HashTable、HashSet笔记

        HashMap底层使用的是数组+单链表的结构,HashMap中存放的键值对(key-value)并且会把他们存储在Map.Entry中,其中Map.Entry中存储的是key的hashcode、value值以及下一个Entry对象的引用next。HashMap实现了Map接口其中最常用的方法就是put(K key,V value)get(Object key)方法,其中put方法的原理是检查key值是否为null,如果为null则将其放入数组的index为0位置。如果当前key不为0,则对该key值取hashCode,并对改hashCode进行位运算,这样做的原因是为了避免哈希碰撞。最后将获取的值hash对数组长度取余数,但是考虑到位位运算的高效性,这里对获取的值hash与数组的长度-1进行&位运算(例如数组的长度是8,那么数组长度-1为7,二进制九尾0111)这样保留的是低位的值。获取到需要插入的值在数组中的index后,如果数组该位置处有值并且该位置的Entry的hash值与被插入的值相同,与此同时key值相同(“==”或者equals相同)那么该位置的value直接替换为将要插入的value值。假如index对应的位置为null或者index对应的位置的Entry不满足hash值相同并且key值相同(“==”或者equals相同)那么直接将被插入的值放入到数组中index位置处,如果该位置有Entry对象,那么作为被插入Entry的next节点向后移动。

get方法也是根据key的hashcode进行位运算然后获取到index,然后遍历该位置的数组和链表值,如果存在Entry的hashcode和该对象的key相同并且与该key相等(“==”或者equals相同),那么返回该值,否则返回null。HashMap允许键值对key-value为null。

       HashTable和HashMap实现了Map接口,基于数组+单链表的结构并且存储的也是键值对,其中比较重要的方法也是Map接口中的put方法和get方法。其中HashTable的put方法与HashMap的相同只是HashMap中如果value为null的话就会抛出异常,当key不为null的时候剩余的判断方式与HashMap相同。如果存在hashcode相同并且key值相同(“==”或者equals相同)的情况那么直接替换value值。否则index处添加新的Entry对象并且原有值作为被插入对象的next。与HashMap相比,HashTable不允许键值对key-value为null,因为只要有一个为null就会抛出异常,并且HashTable是线程安全的,查看起public方法可以发现都有synchronize的修饰。

       基于以上的理解可以得知HashMap中存入数据是无序的也就是说通过EntrySet的iterator方式打印出的HashMap中的值和put进去的值的顺序不一致。而LinkedHashMap可以做到输入和输出的顺序相同。LinkedHashMap继承了HashMap并实现了Map接口所以其也有put和get方法,并且LinkedHashMap的数据结构也是数组+链表的数据结构,但是LinkeHashMap维护着一个运行于所有条目的双重链接列表,此链接列表定义了迭代顺序,该迭代顺序可以是顺序插入或者访问顺序,默认是按顺序插入排序,如果指定访问顺序后,调用get方法后会将这次访问的元素移至双重连接列表的尾部,不断的访问可以形成按访问顺序排列的链表。LinkedHashMap允许存入key-value均为null,并且键值对也是用Map.Entry来封装,不过增加了两个变量分别是Entry<K,V>before,after表该Entry在双链表中的前一个节点和后一个节点。

        LinkedHashMap的put方法和HashMap相同,更具key的hashcode计算出键值对在数组中的index,如果遇到index位置有值并且hashcode和被插入的值相同并且key相同(“==”或者equals相同)那么直接替换value值。如果index的值不满足以上条件那么在相应的位置插入新值,并且双链表中将该值放入尾部,并处理该Entry的after和before的指向。如果该值在双链表中已经存在那么双链表中remove掉之前的值,将该值加到双链表的尾部。如果想按照访问顺序输入LinkedHashMap中的值,那么在构造该对象的时候accessOrder出入true,在进行get方法后,执行上述将Entry对象放入双链表的尾部。如果该值设置为false的话则不执行插入双链表的尾部的逻辑。

        HashSet的特点是不允许存入相同的值,其原因是HashSet的底层是一个HashMap,并且HashSet中存入的值是作为HashMap的vaule值,而key是Object对象,所以存入相同的key的时候显示是一样的。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值