当前位置 : 主页 > 编程语言 > 其它开发 >

HashMap简单实现

来源:互联网 收集:自由互联 发布时间:2022-05-30
import java.util.*;/** * @Author nanfengnan * @Date 2022/4/19 * @Description 自己实现的HashMap * 哈希函数:hashCode()+除留余数法 * 冲突解决:链地址法 */public class ThirdHashMapK, V { /** * 链表节点 * @param K * @par
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;
            }
        }
    }
    
}

上一篇:转【SOLID 原则的可靠指南】
下一篇:没有了
网友评论