• 手写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 }
  • 相关阅读:
    C# color颜色对照表
    图纸目录
    autocad.net中各种id、实体、表记录间的访问代码,持续更新中……
    autocad.net通过支持文件搜索路径查找文件
    autocad.net中数据结构(blocktable,blocktablerecord,blockreference,layout,ModelSpace,PaperSpace)
    autocad.net回退undo与命令行回应cmdecho完美结合
    autocad.net中blocktable,blocktablerecord,blockreference,modelspace,paperspace,layout,viewport的关系(待进一步测试)
    ObjectARX SDK 全部版本下载至2013
    autocad.net中设置系统变量
    在autocad.net中加载lisp程序的方法
  • 原文地址:https://www.cnblogs.com/MrliBlog/p/11005088.html
Copyright © 2020-2023  润新知