HashMap

//hashmap实现了Map接口,并继承了AbstractMap类
//map接口里面定义了键值对。
public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {
}
//其有四个构造方法:
//第一个是创造了一个一定容量和阈值的空的hashmap
public HashMap(int initialCapacity, float loadFactor) {
    //传入空间为空,抛出异常
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
    //传入空间如果太大,则规定为最大空间。 
    //static final int MAXIMUM_CAPACITY = 1 << 30;
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
    //负载因子小于0,则抛出异常
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
    //将传进来的负载因子赋值给创建的hashmap
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }
//确定hashmap的空间,需要保证其为2的幂
static final int tableSizeFor(int cap) {
    //-1在二级制中是32个1表示的,
        int n = -1 >>> Integer.numberOfLeadingZeros(cap - 1);
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
//这个是返回数字最高位0的个数
//二分的思想:先确定其在哪一位(16位左边高位?还是右边低位),继续二分,直到确定其位置
//然后可以得出其高位至少有的0的个数,再将其划分区间的右边低位全部通过“>>>”方式去掉。n代表其最大可能的0的个数,n也同时更新。
public static int numberOfLeadingZeros(int i) {
        // HD, Count leading 0's
        if (i <= 0)
            return i == 0 ? 32 : 0;		//传进来的为0的话,返回32个0
        int n = 31;
        if (i >= 1 << 16) { n -= 16; i >>>= 16; }
        if (i >= 1 <<  8) { n -=  8; i >>>=  8; }
        if (i >= 1 <<  4) { n -=  4; i >>>=  4; }
        if (i >= 1 <<  2) { n -=  2; i >>>=  2; }
        return n - (i >>> 1);
    }


//第二个是创建一定空间的空hashmap
 public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

//第三个是无参构造
public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
    }

//第四个是创建一个与指定Map有相同映射的hashmap
//??????????
public HashMap(Map<? extends K, ? extends V> m) {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        putMapEntries(m, false);
    }

这里面节点的定义如下:

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

可以看出来,其实现了map.entry接口,这是键值对实现的节点,存储的是键值对。

(本来打算把源码好好看一下,写好了再发上来,可是时间不够,而且那个树节点的增减看着头痛,以后有机会再看吧)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值