• 数据结构之手写HashMap


    一:HashMap和HashSet特点

    HashMap
    1)HashMap的key和value都可以为null,key不可以重复,只要key一样就会把之前的覆盖掉。
    2)HashMap是无序的,线程不安全的
    3)Hashtable是Map的古老实现类;线程安全的,效率低;因为锁的是整个map。不可以存储null的key和value
    HashSet
    1)HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
    2)HashSet 允许有 null 值。
    3)HashSet 是无序的,即不会记录插入的顺序。
    4)HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
    5)HashSet 实现了 Set 接口。

    二:HashMap

    1.定义map接口

    public interface Map<K,V> {
        /**
         * put方法
         * @param k
         * @param v
         * @return
         */
        V put(K k,V v);
        /**
         * get方法
         * @param k
         * @return
         */
        V get(K k);
        /**
         * map长度
         * @return
         */
        int size();
        /**
         *
         * @param 
         * @param 
         */
        interface Entry<K,V>{
            /**
             * 获取key
             * @return
             */
            K getKey();
            /**
             * 获取value
             * @return
             */
            V getValue();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    2.定义HashMap并且实现Map

        Entry<K,V>[] table = null;
        int size = 0;
        public HashMap(){
            table = new Entry[16];
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • HashMap底层就是一个数组,默认长度是16

    3.对hashMap的key进行hash算法

        private int hash(K k){
            int index = k.hashCode() % 16;
            return index>=0?index:-index;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 对hashMap的key值进行hash算法,取模算出下标

    4.重写get和put方法

        @Override
        public V get(K k) {
            int index = hash(k);
            Entry<K, V> entry = findValue(table[index],k);
            return entry==null?null:entry.getValue();
        }
    
        @Override
        public V put(K k, V v) {
            int index = hash(k);
            Entry<K, V> entry = table[index];
            if(null == entry){
                table[index] = new Entry<>(k, v, index, null);
                size++;
            } else {
                table[index] = new Entry<>(k, v, index, entry);
            }
            return table[index].getValue();
        }
        @Override
        public int size() {
            return 0;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    1.key进行hash,取模算出index下标
    2.找到数组对应的节点对象,判断对象是否为空
    3.如果为空,直接返回空对象
    4.如果不为空,用查出来的k和当前k做比较
    1):如果相等,直接返回数据
    2):如果不相等,查询next是否为空,为空直接返回
    3):如果不为空,查询取出来的key和当前的key是否相等,直到相等为止

    5.在entry数组中,找到指定key所对应的value值

     public Entry<K,V> findValue(Entry<K, V> entry,K k){
            if (k.equals(entry.getKey()) || k == entry.getKey()){
                return entry;
            } else {
                if( entry.next != null){
                    return findValue(entry.next, k);
                }
            }
            return null;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6.重写entry数组

     class Entry<K,V> implements Map.Entry<K,V>{
            K k;
            V v;
            int index;
            Entry<K,V> next;
            public Entry(K k, V v, int index, Entry<K, V> next) {
                this.k = k;
                this.v = v;
                this.index = index;
                this.next = next;
            }
            @Override
            public K getKey() {
                return k;
            }
            @Override
            public V getValue() {
                return v;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    docker安装gitlab 并dump出表结构
    数据分析思维模型和方法
    阿尔兹海默病智能诊断
    【高级算法设计与分析】实验2:单向与双向A*搜索算法
    C语言-控制语句
    Unity中使用自定义mesh和UImesh
    【R-CNN系列目标检测】R-CNN算法
    01.OpenWrt-写在前面
    c++内存管理
    OGAI详解:AIStation调度平台如何实现大模型高效长时间持续训练
  • 原文地址:https://blog.csdn.net/suiyishiguang/article/details/125874751