手写HashMap,带注解

代码不全,觉得重要的就写下去,直接运行是运行不了的,主要是我后面懒了。。。
但是大概思路还是有的
等不懒的时候再补补

import javax.xml.soap.Node;
import java.io.Serializable;
import java.util.*;

/**
 * @author chy
 * @create 2020-12-04-15:45
 */
public class MyHashMap<K,V> extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable, Serializable {
    /** 默认大小*/
    private int DEFAULT_SIZE = 1 << 4;
    /** 最大值*/
    private int MAX_SIZE = 1 << 30;

    /** 扩容因子*/
    private float DEFAULT_LOAD_FACTOR = 0.75f;

    /** 含量大小*/
    private int size;
    /** 实际的扩容因子 */
    private float loadFactor;
    /** 实际大小*/
    private int threshold;

    transient int modCount;

    /**
     * 存放节点的数组
     */
    transient MyNode<K,V>[] table;

    /**
     * 计算hash值
     * @param key
     * @return
     */
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    /**
     * 构造函数
     * @param initSize 初始化大小
     * @param loadFactor 扩容因子
     */
    public MyHashMap(int initSize, float loadFactor) throws Exception {
        if (initSize < 0){
            throw new Exception("大小不能为负数");
        }

        if (0 >=loadFactor){
            throw new Exception("大小不能为0");
        }

        if (1 <loadFactor){
            throw new Exception("大小不能大于1");
        }

        if (initSize > this.MAX_SIZE){
            initSize = this.MAX_SIZE;
        }

        this.threshold = tableSizeFor(initSize);
        this.loadFactor = loadFactor;
    }

    /**
     *
     */
    public MyHashMap(){
        this.loadFactor = DEFAULT_LOAD_FACTOR;
    }

    /**
     * 获取大于等于 目标值的最小的2的幂,便于hash计算
     * @param size
     * @return
     */
    public int tableSizeFor(int size){
        int n = size -1;
        n |= n>>>1;
        n |= n>>>2;
        n |= n>>>4;
        n |= n>>>8;
        //最大只有30位,右移16够了
        n |= n>>>16;
        return n<0? 1 : n >= MAX_SIZE ? MAX_SIZE : n+1;
    }

    /**
     * 根据key跟hash获取节点
     * @param hash
     * @param key
     * @return
     */
    final MyNode<K,V> getNode(int hash, Object key) {
        MyNode<K,V>[] tab; MyNode<K,V> first, e; int n; K k;
        //判断table是否初始化
        if ((tab = table) != null && (n = tab.length) > 0 &&
                //获取头节点
                (first = tab[(n - 1) & hash]) != null) {
            //头节点是否是目标值
            if (first.hash == hash && 
                    ((k = first.key) == key || (key != null && key.equals(k)))) {
                return first;
            }
            //遍历节点队列
            if ((e = first.next) != null) {
                do {
                    if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k)))) {
                        return e;
                    }
                } while ((e = e.next) != null);
            }
        }
        return null;
    }

    /**
     * 获取value,当节点不存在返回defualtValue
     * @param key
     * @param defaultValue
     * @return
     */
    @Override
    public V getOrDefault(Object key, V defaultValue) {
        MyNode<K,V> e;
        return (e = getNode(hash(key), key)) == null ? defaultValue : e.value;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size > 0;
    }

    @Override
    public boolean containsKey(Object key) {
        return getNode(hash(key),key) != null;
    }

    @Override
    public boolean containsValue(Object value) {
        MyNode<K,V>[] table = this.table;
        V v;
        // 判断table是否为空
        if (table!=null && size >0){
            //遍历table
            for (int i = 0; i < table.length; ++i) {
                //遍历MyNode 列表
                for (MyNode<K,V> n = table[i]; n != null; n = n.next){
                    if ((v = n.value) == value ||
                        (value != null && value.equals(v))){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public V get(Object key) {
        MyNode<K,V> node;
        return (node = getNode(hash(key),key)) == null? null : node.value;
    }

    @Override
    public V put(K key, V value) {
        return putVal(hash(key),key,value);
    }

    /**
     * 
     * @param hash
     * @param key
     * @param value
     * @return
     */
    final V putVal(int hash, K key, V value){
        MyNode<K,V>[] tab; MyNode<K,V> p; int n, i;
        // 如果table没有初始化,则为table初始化
        if ((tab = table) == null || (n = tab.length) == 0) {
            n = (tab = resize()).length;
        }
        //hash不存在,则新加入节点到对应hash
        if ((p = tab[i = (n - 1) & hash]) == null) {
            tab[i] = new MyNode(hash, key, value, null);
        } else {
            MyNode<K,V> e; K k;
            //key已经存在
            if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k)))) {
                e = p;
            //hash 相等,key不等
            } else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = new MyNode(hash, key, value, null);
                        //如果大于 8(可更改),则转换为红黑树
//                        if (binCount >= TREEIFY_THRESHOLD - 1){
//                            treeifyBin(tab, hash);
//                        }
//                        break;
                    }
                    if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k)))) {
                        break;
                    }
                    p = e;
                }
            }
            if (e != null) {
                V oldValue = e.value;
                if ( oldValue == null) {
                    e.value = value;
                }
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold) {
            resize();
        }
        return null;
    }

    @Override
    public V remove(Object key) {
        return null;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {

    }

    @Override
    public void clear() {

    }

    @Override
    public Set<K> keySet() {
        Set<Map.Entry<K,V>> es;
        return (es = entrySet) == null ? (entrySet = new HashMap.EntrySet()) : es;
    }

    @Override
    public Collection<V> values() {
        return null;
    }

    @Override
    public Set<Map.Entry<K, V>> entrySet() {
        return null;
    }

    @Override
    public boolean equals(Object o) {
        return false;
    }

    @Override
    public int hashCode() {
        return 0;
    }

    class MyNode<K,V> implements Map.Entry<K,V>{
        final int hash;
        final K key;
        V value;
        MyNode<K,V> next;
        MyNode(int hash, K key, V value, MyNode<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

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


    public static void main(String[] args) {
        MyHashMap myHashMap = new MyHashMap();
        System.err.println(myHashMap.DEFAULT_SIZE +" "+myHashMap.MAX_SIZE);

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值