手写简单的HashMap

前言

  1. 在Java集合中,Map是一种特殊的集合,原因在于这种集合容器并不是保存的单个元素,而是一个个的key-value键值对。HashMap是基于哈希表的Map接口的实现,在项目开发中,这种集合使用是非常广泛的,本文主要就是对HashMap的底层原理做个剖析。

HashMap特点

  1. HashMap是基于哈希表的Map接口实现。
  2. HashMap底层采用的是Entry数组和链表实现。
  3. HashMap是采用key-value形式存储,其中key是可以允许为null但是只能是一个,并且key不允许重复(如果重复则新值覆盖旧值)。
  4. HashMap是线程不安全的。HashMap存入的顺序和遍历的顺序有可能是不一致的。
  5. HashMap保存数据的时候通过计算key的hash值来去决定存储的位置。

话不多说上代码

package hashMap;
  2 
  3 public class MyHashMap<K, V> {
  4 
  5     private Entry<K, V>[] table;//Entry是hashMap的一个内部类,是真正存放数据的类
  6     private static final Integer CAPACITY = 8;// hashMap初始长度
  7     private int size;//集合元素的个数
  8 
  9     // 存或修改元素
 10     public void put(K k, V v) {
 11       //如果是第一次存放,就初始化数组
 12         if (table == null) {
 13             inflate();
 14         }
 15         // 存entry
 16         // 根据k的值返回一个int类型的hashCode
 17         int hashCode = hash(k);
 18         // 根据这个hashCode返回一个数组下标,index是在0~table.length之间的数,不会数组越界
 19         int index = indexOf(hashCode);
 20         // 如果放入的k已存在,那么将参数k赋值个原先存在的元素,参数v赋值给该元素,达到更新的目的
 21         boolean flag = true;
 22         for (Entry<K, V> entry = table[index]; entry != null; entry = entry.next) {
          //判断是否存在相同的k
 23             if (entry.key.equals(k)) {
 24                 entry.key = k;
 25                 entry.value = v;
 26                 flag = false;
 27             }
 28         }
 29         // 如果存在相同的k就不再执行添加方法
 30         if (flag) {
 31             addEntry(k, v, index);
 32         }
 33 
 34     }
 35 
 36     // 取
 37     public V get(K k) {
 38         // 根据k的值返回一个hashCode
 39         int hashCode = hash(k);
 40         // 根据这个hashCode返回一个数组下标
 41         int index = indexOf(hashCode);
 42         // 根据传入的k计算出table数组的下标index,然后循环判断这个index位置是否存在这个k,如果存在就返回该entry的value,如果不存在就返回null
 43         for (Entry<K, V> entry = table[index]; table[index] != null; entry = entry.next) {
 44             if (entry.key.equals(k)) {
 45                 return entry.value;
 46             }
 47         }
 48 
 49         return null;
 50     }
 51   //添加方法,把最新添加的entry元素放进table数组index位置,把原先在index位置的元素作为新添元素的下一个元素(他的属性)
 52     private void addEntry(K k, V v, int index) {
 53         Entry<K, V> newEntry = new Entry<>(k, v, table[index]);
 54         table[index] = newEntry;
 55         // 每存入一个元素数组的元素个数就加一
 56         size++;
 57 
 58     }
 59 
 60     private int indexOf(int hashCode) {
 61       //用得到的hashCode值对数组长度取模,保证不会现数组越界的错误
 62         return hashCode % table.length;
 63     }
 64   //返回k值的hashcode值
 65     private int hash(K k) {
 66 
 67         return k.hashCode();
 68     }
 69   //初始化table数组
 70     private void inflate() {
 71         table = new Entry[CAPACITY];
 72 
 73     }
 74   //内部类,存储数据的实体
 75     class Entry<K, V> {
 76         private K key;
 77         private V value;
 78         private Entry<K, V> next;
 79 
 80         public Entry(K key, V value) {
 81         82             this.key = key;
 83             this.value = value;
 84         }
 85 
 86         public Entry(K key, V value, Entry<K, V> next) {
 87          88             this.key = key;
 89             this.value = value;
 90             this.next = next;
 91         }100 
101     }
102   //测试
103     public static void main(String[] args) {
104         MyHashMap<String, String> myHashMap = new MyHashMap<>();
105         myHashMap.put("1", "1p");
106         myHashMap.put("1", "1pp");
107         myHashMap.put("2", "2p");
108         System.out.println(myHashMap.get("1"));//1pp,out()方法即是存放又是修改
109         System.out.println(myHashMap.size);//2
110     }
111 
112 }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值