HashMap底层原理(6)--- 手写HashMap源码

目录
-----第一章
----------为什么要深入学习HashMap?
----------HashMap与HashTable的区别是什么?
----------自定义HashMap中的Entry<K,V>类
----------使用ArrayList集合实现简易版HashMap
----------使用LinkedList链表实现简易版HashMap
----------HashCode和equals的区别
----------如何解决HashCode碰撞问题
----------纯手写HashMap中的put方法
----------纯手写HashMap中的get方法
-----第二章
----------HashSet基本API使用介绍
----------HashSet底层原理分析
----------HashMap底层基本实现原理分析
----------HashMap构造函数实现原理分析
----------HashMap第一次数组扩容原理
----------HashMapPut方法源码分析
-----第三章
----------HashMapJDK1.7面试题总结
----------HashMapJDK1.7扩容死循环原理分析
----------HashMapJDK1.8什么要使用红黑树
----------数据结构中时间复杂度对比
----------二叉搜索树基本实现原理与思想
----------手写二叉搜索树添加功能
----------手写二叉搜索树查询功能
----------总结二叉搜索查询存在哪些问题
-----第四章
----------二叉搜索树存在那些问题
----------红黑树的数据结构基本介绍
----------红黑树基本的特征介绍
----------红黑树变换颜色的规则要求
----------红黑树左右旋转基本的规则
----------手写红黑树环境代码实现
----------手写红黑树实现二叉树
----------红黑树规则破坏如何实现修复
-----第五章
----------手写红黑树左旋转代码演示
----------红黑树基本变色旋转规则回顾
----------纯手写一步一步写左旋转
----------红黑树基本左旋变颜色01
----------红黑树基本左旋变颜色02
----------红黑树基本左旋变颜色03
----------红黑树基本左旋变颜色04
----------红黑树查询左大值与最小值
-----第六章
----------HashMap8基本实现原理分析
----------HashMap8优化了7那些bug
----------HashMap8的Put方法实现原理01
----------HashMap8的Put方法实现原理02
----------HashMap8的Put方法扩容实现
----------HashMap8的Put方法源码分析总结

手写HashMap

public class MyHashMap<K, V> implements MyMap<K, V> {
   
    final float loadFactor; // 实际负载因子
  
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;  // 初始容量默认为16
  
    static final float DEFAULT_LOAD_FACTOR = 0.75f;// 默认负载因子0.75f,越小越早扩容,数据分布越散

    int threshold; //阈值 = 负载因子 * 容量

    Entry[] table; //数组
  
    transient int size; 

	//空构造,使用默认值创建HashMap
    public MyHashMap() {
    
        this.loadFactor = DEFAULT_LOAD_FACTOR;//实例负载因子 = 默认负载因子 = 0.75f
        
        threshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);//确定阈值
        
        table = new Entry[DEFAULT_INITIAL_CAPACITY]//创建数组
        
        init();//空方法,子类扩展
    }

    void init() {
    }

    public int size() {
        return this.size;
    }

    public V put(K key, V value) {
        // 1.计算hash值
        int hash = hash(key);
        // 计算index
        int i = indexFor(hash, table.length);
        // 判断是否有hash碰撞的问题,如果发生hash碰撞问题,hashCode相同且对象的值内容不同
        for (Entry<K, V> e = table[i]; e != null; e = e.next) {
            if (e.getKey().equals(key)) {
                // 获取原来的值
                V oldValue = e.getValue();
                // 设置新值
                e.setValue(value);
                return oldValue;
            }
        }
        //如果没有发生hash碰撞问题,链表中添加元素
        addEntry(hash, key, value, i);
        return null;
    }

    private void addEntry(int hash, K key, V value, int bucketIndex) {
        // 获取Entry对象
        Entry<K, V> e = table[bucketIndex];
        table[bucketIndex] = new Entry(key, value, e, hash);
    }


    static int indexFor(int h, int length) {
        return h & (length - 1); // -1是为了使计算出来的值分布的均匀,是奇数
    }

    public V get(K key) {
        return null;
    }


    private int hash(K key) {
        int hashCode = key.hashCode();
        int hash = hashCode % table.length;
        return hash;
    }

    static class Entry<K, V> implements MayiktMap.Entry<K, V> {
        // key
        private K k;
        // value
        private V v;
        // 下一个节点
        Entry<K, V> next;
        /**
         * hash值
         */
        private int hash;

        public Entry(K k, V v, Entry<K, V> next, int hash) {
            this.k = k;
            this.v = v;
            this.next = next;
            this.hash = hash;
        }

        public K getKey() {
            return this.k;
        }

        public V getValue() {
            return this.v;
        }

        public V setValue(V value) {
            this.v = v;
            return this.v;
        }

        public Entry(K k, V v) {
            this.k = k;
            this.v = v;
        }
    }
}
发布了12 篇原创文章 · 获赞 2 · 访问量 315

猜你喜欢

转载自blog.csdn.net/qq_42972645/article/details/104001586