Hashmap的简单原理实现与代码分析

在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时候,其散列状态会变为规则状态,小伙伴们可以思考思考其底层实现原理如何

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值