• HashMap简单实现


    import java.util.*;
    
    /**
     * @Author nanfengnan
     * @Date 2022/4/19
     * @Description 自己实现的HashMap
     * 哈希函数:hashCode()+除留余数法
     * 冲突解决:链地址法
     */
    public class ThirdHashMap<K, V> {
        /**
         * 链表节点
         * @param <K>
         * @param <V>
         */
        class Node<K,V>{
            private K key;
            private V value;
            private Node<K,V> next;
    
            public Node(K key,V value){
                this.key = key;
                this.value = value;
                this.next = null;
            }
        }
        // 默认容量
        final int DEFAULT_CAPACITY = 16;
        // 负载因子
        final float LOAD_FACTOR = 0.75f;
        // HashMap的大小
        private int size;
        // 桶数组
        Node<K,V>[] buckets;
    
        /**
         * 两个构造函数,用于初始化桶的大小
         */
        public ThirdHashMap() {
            buckets = new Node[this.DEFAULT_CAPACITY];
            this.size = 0;
        }
        public ThirdHashMap(int capacity) {
            buckets = new Node[capacity];
            this.size = 0;
        }
    
        /**
         * 哈希函数:采用除留余数法
         * @param key
         * @param length
         * @return 哈希地址
         */
        public int getIndex(K key,int length) {
            // 获取hash code ,32位带符号数
            int hashCode = key.hashCode();
            // 除留余数法
            return Math.abs(hashCode % length);
        }
    
        /**
         * 得到value方法
         * @param key
         * @return
         */
        public V get(K key) {
            // 获得key的哈希地址
            int index = getIndex(key, buckets.length);
            Node<K, V> node = buckets[index];
            // buckets[index]里面没有数据
            if (node == null)
                return null;
            // 否则遍历链表
            while (node != null) {
                // 考虑字符串使用equals
                if ((node.key.hashCode() == key.hashCode())
                        && (node.key == key || node.key.equals(key))) {
                    return node.value;
                }
                node = node.next;
            }
            return null;
        }
    
        /**
         * put方法
         * @param key
         * @param value
         */
        public void put(K key,V value) {
            // 判断是否超过负载空间
            if (size >= buckets.length*LOAD_FACTOR)
                resize();
            putValue(key,value,buckets);
        }
    
        /**
         * 得到桶中元素个数
         * @return
         */
        public int size() {
            return this.size;
        }
    
        /**
         * 删除key
         * @param key
         */
        public Node<K,V> remove(K key) {
            // 得到哈希地址
            int index = getIndex(key, buckets.length);
            if (buckets[index] == null)
                return buckets[index];
            else if ((buckets[index].key.hashCode() == key.hashCode()) 
                    && (buckets[index].key == key || buckets[index].key.equals(key))) {
                Node<K,V> t = buckets[index].next;
                buckets[index].next = t.next;
                return t;
            }
            Node<K,V> node = buckets[index].next;
            Node<K,V> pre = node;
            while (node != null) {
                // 找到了key,则断链删除元素
                if ((node.key.hashCode() == key.hashCode())
                && (node.key == key || node.key.equals(key))) {
                    pre.next = node.next;
                    return node;
                }
                pre = pre.next;
                node = node.next;
            }
            // 否则,桶中没有此元素
            return null;
        }
    
        /**
         * containsKey
         * @param key
         * @return
         */
        public boolean containsKey(K key) {
            for (int i = 0; i < buckets.length; i++) {
                if (buckets[i] == null)
                    continue;
                Node node = buckets[i];
                while (node != null) {
                    if ((node.key.hashCode() == key.hashCode())
                    && (node.key == key || node.key.equals(key)))
                        return true;
                    node = node.next;
                }
            }
            return false;
        }
    
        /**
         * containsValue
         * @param value
         * @return
         */
        public boolean containsValue(V value) {
            for (int i = 0; i < buckets.length; i++) {
                if (buckets[i] == null)
                    continue;
                Node node = buckets[i];
                while (node != null) {
                    if ((node.value == value || node.value.equals(value)))
                        return true;
                    node = node.next;
                }
            }
            return false;
        }
        
        /**
         * 得到keySet
         * @return
         */
        public Set<K> keySet() {
            Set<K> set = new HashSet<K>();
            for (int i = 0; i < buckets.length; i++) {
                if (buckets[i] == null)
                    continue;
                Node<K,V> node = buckets[i];
                while (node != null) {
                    set.add(node.key);
                    node = node.next;
                }
            }
            return set;
        }
    
        /**
         * 得到values
         * @return
         */
        public Collection<V> values() {
            Collection<V> collection = new ArrayList<V>();
            for (int i = 0; i < buckets.length; i++) {
                if (buckets[i] == null)
                    continue;
                Node<K,V> node = buckets[i];
                while (node != null) {
                    collection.add(node.value);
                    node = node.next;
                }
            }
            return collection;
        }
    
        /**
         * 向桶中添加元素,也可以当作复制元素使用
         * @param key
         * @param value
         * @param table
         */
        public void putValue(K key,V value,Node<K,V>[] table) {
            // 获取哈希地址,判断是否存在
            int index = getIndex(key, table.length);
            // 得到table[index]元素
            Node<K,V> node = table[index];
            // 桶中没有元素
            if (node == null) {
                table[index] = new Node<K, V>(key,value);
                size++;
                return;
            }
            // 冲突,使用链地址法
            while (node != null) {
                // key相同则修改,考虑字符串
                if ((node.key.hashCode() == key.hashCode())
                && (node.key == key || node.key.equals(key))) {
                    node.value = value;
                }
                node = node.next;
            }
            // 没有该映射,添加到链表的头部
            Node<K,V> t = new Node<K, V>(key,value);
            t.next = table[index].next;
            table[index].next = t;
            size++;
        }
    
        /**
         * 扩容函数
         */
        private void resize() {
            // 扩容2倍
            Node<K,V>[] newbuckest = new Node[buckets.length<<1];
            // 将当前元素写入newbuckets桶中
            rehash(newbuckest);
            // buckets指向newbuckets
            buckets = newbuckest;
        }
    
        /**
         * 将酒桶的元素复制到新的桶中
         * @param newbuckets
         */
        private void rehash(Node<K,V>[] newbuckets) {
            size = 0;
            for (int i = 0; i < buckets.length; i++) {
                if (buckets[i] == null)
                    continue;
                // 复制链表节点
                Node<K,V> node = buckets[i];
                while (node != null) {
                    putValue(node.key,node.value,newbuckets);
                    node = node.next;
                }
            }
        }
        
    }
    
    
  • 相关阅读:
    jmeter处理加密接口
    jmeter的环境配置
    jmeter的一些知识目录
    monkey 基本用法
    python3.6连接数据库 小微工作笔记
    jenkins 配置任务
    HTTP 状态大全
    【Codeforces】894E.Ralph and Mushrooms Tarjan缩点+DP
    【Codeforces】894D. Ralph And His Tour in Binary Country 思维+二分
    【Codeforces】879D. Teams Formation 思维+模拟
  • 原文地址:https://www.cnblogs.com/nanfengnan/p/16167614.html
Copyright © 2020-2023  润新知