在jdk1.8之前 HashMap的实现原理为链表加数组,在1.8之后版本的更新迭代 ,原理变成了数组+链表与红黑树完成
这里先简单实现下hashMap的链表加数组的实现
其中数组中每个元素都是一个单链表 ,再通过其Entry值去存放HashMap中的key与Value值。
下面来简单通俗来介绍,
HashMap的存储再内存中是散列排布的,如下所示
import java.util.HashMap;
import java.util.Set;
public class HashMap_31 {
public static void main(String[] args) {
HashMap<String,Integer> hashMap=new HashMap<>();
hashMap.put("hello01",1);
hashMap.put("hello02",2);
hashMap.put("hello03",3);
//获取其key值
Set<String> hash=hashMap.keySet();
for(String str:hash){
System.out.print(str+" ");
System.out.println(hashMap.get(str));
}
}
}
可见在HashMap中是散列存放的,这主要得益于如下:
其HashMap的key值是无法相同的,于是就通过去对输入的内容进行某种操作,这里用hashcode来表述,内容如下:
import java.util.HashMap;
public class HashMap_31 {
public static void main(String[] args) {
HashMap<String,String> hashMap=new HashMap<>();
hashMap.put("hello01","Gu");
hashMap.put("hello01","gu");
System.out.println(hashMap.get("hello01"));
}
}
在当其重复的时候会被后者加入的key与value覆盖
这是因为存储是这样的
import java.util.HashMap;
public class HashMap_31 {
public static void main(String[] args) {
HashMap<String,String> hashMap=new HashMap<>();
hashMap.put("hello01","Gu");
HashMap<String,String>hashMap1=new HashMap<>();
hashMap1.put("hello01","Gu");
System.out.println(hashMap.hashCode());
System.out.println(hashMap1.hashCode());
}
}
可以发现其hashcode是一样的,这是因为是key值是相同的,所以最后会存放在一个位置里面,
若想解决这个问题就需要去使用到单链表,将重复的内容去放到链表中吗,在数据重复过多之后,则会去将链表转为红黑树的结构
这里就简单的实现其中的get和put方法,源码如下
package Frame.HashMap;
//简易实现hashmap
public class wLHashMap<K,V> {
private Entry[]kvEntry=new Entry[100];
class Entry<K,V>{//存放键值对
K key;
V value;
int hash;
Entry<K,V> next;
public Entry(K key, V value,int hash) {
this.key = key;
this.value = value;
this.hash=hash;
}
}
public void put(K key,V value){
int hash=key.hashCode();
int index=hash% kvEntry.length;
Entry entry=kvEntry[index];
if(entry==null){//避免hash冲突
kvEntry[index]=new Entry(key,value,hash);
}else{
entry.next=new Entry<>(key,value,hash);
}
}
public V get(K key){
int hash=key.hashCode();
int index= hash% kvEntry.length;
for(Entry<K,V> entry=kvEntry[index];entry!=null;entry=entry.next){
if(entry.hash==hash&&(entry.key==key||entry.key.equals(key))){
return entry.value;
}
}
return null;
}
}
对该代码实现如下
public static void main(String[] args) {
wLHashMap<String, String> wLHashMap = new wLHashMap<>();
wLHashMap.put("hello01","wanglei");
wLHashMap.put("hello02","Baby_Gu");
System.out.println(wLHashMap.get("hello01"));
// System.out.println(wLHashMap.get("hello01"));
}
其次会出现有hash冲突,例如两个hashMap的key值依次是a和97的时候,其位置会在一个,这个就会造成其数据的问题,
因此我们需要去重写hashcode,与此同时也就是需要去重写equals方法,将会在后面文章中提出
后述当key为Interage时候,其散列状态会变为规则状态,小伙伴们可以思考思考其底层实现原理如何