- HashMap解析
- 底层结构:Map是由数组+链表实现,链表里存储的是每个Entry<k,v> 如图:
- HashCode 和Equals
- ①当每个entry存入到链表需要计算出每个key的hashcode的值,每个hashcode的值都是唯一的,hashcode决定数组值的存放位置,这也就是map的不可重复的特性之一;
- ②遇到插入出现的两个相同hashCode值就会覆盖上一个value值,而保留后面插入的entry<key value>
- ③hashCode作为插入和查找的唯一值,使map的执行效率非常高;hashcode相等(就是key相等)不一定value值相等,value值相等那么key的hashcode就一定相等
- ④重写equals就必须重写hashcode值如果当两个对象值相等返回true,此时hashcode若没重写就出现不一样的hash值,存储的内存地址也不一样,这样在HashSet和Map使用造成致命的错误(key的唯一性会被破坏)
- 相关详细解释:https://blog.youkuaiyun.com/u013679744/article/details/57074669
- 自主简单实现HashMap
-
Put方法 public void put(Object key,Object value) { int a=key.hashCode()%myEntry.length;//求余,尽量避免哈希冲突 int hash=(a<0)?-a:a;//考虑哈希值为负数的情况 Entry entry=new Entry(key,value);//每插入一次就有一个entry if(myEntry[hash]==null) //对数组对象判断 { LinkedList linkedList=new LinkedList();//如果hash位置的值为null,在该位置生成链表 myEntry[hash]=linkedList;//将链表交由数组对象 linkedList.add(entry);//每增加一个entry就添加进链表 } else//数组对象存在的情况下{ LinkedList list=myEntry[hash];//把该值交由链表管理 for (int i = 0; i < list.size(); i++) { Entry e=(Entry) list.get(i);//将链表数遍历查找出来比较 if(e.key.equals(key)) { e.value=value;//key值相同,覆盖原值 return; } } } } 查找方法get public Object get(Object key) { int a = key.hashCode()%myEntry.length; if(myEntry[a]!=null) { LinkedList list=myEntry[a]; for (int i = 0; i < list.size(); i++) { Entry e=(Entry) list.get(i); if(e.key.equals(key)){ return e.value; } } } return null; }