手写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值来去决定存储的位置。

话不多说上代码

  

  1 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 }

猜你喜欢

转载自www.cnblogs.com/MrliBlog/p/11005088.html