HashMap源码--(五)Entry

HashMap源码–(五)Entry

HashMap继承了Map,HashMap.Entry实现了Map.Entry类,并实现了Entry类里的方法。
Entry的实现是一个链表。它的属性包括key、value、next、hash。
HashMap存数据是以key-value的键值对方式,实际HashMap存的是Entry数组,key-value就是Entry对象key和value属性。
Entry类的属性和构造器如下:

static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        Entry<K,V> next;
        final int hash;

        /**
         * Creates new entry.
         */
        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }
}

这里的key是用final定义的,可以看出对于Entry对象来说,key值只能被赋值一次。key也可以赋null。key主要的作用就是用于计算哈希值得出存放位置,使数据快速存取。上面说了HashMap中存放的就是Entry,那在HashMap在存值时,由于key值是final的,不能再次被赋值,所以会先匹配key值是否存在,如果存在,则key对应的Entry对象的value将被覆盖,如果不存在,则创建Entry对象。HashMap取值时,根据key来取值的方式最常用。
Entry类中包含了获取key和value的方法,也包括equals、hashCode、toString,Entry还有两个没有方法内容的方法,如下:

        public final K getKey() {return key;}
        public final V getValue() {return value;}
        public final V setValue(V newValue) {
        V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry e = (Map.Entry)o;
            Object k1 = getKey();
            Object k2 = e.getKey();
            if (k1 == k2 || (k1 != null && k1.equals(k2))){
                Object v1 = getValue();
                Object v2 = e.getValue();
                if (v1 == v2 || (v1 != null && v1.equals(v2)))
                    return true;
            }
            return false;
        }

        public final int hashCode() {
            return (key==null   ? 0 : key.hashCode()) ^
                   (value==null ? 0 : value.hashCode());
        }

        public final String toString() {return getKey() + "=" + getValue();}

        /**
         * 该方法用于key值存在,value被覆盖时
         */
        void recordAccess(HashMap<K,V> m) {}
        /**
         * 该方法用于entry被移除时
         */
        void recordRemoval(HashMap<K,V> m) {}

对Entry操作的方法有addEntry、createEntry等,这些操作方法可以看出Entry链表的存储方式,如下:

    /**
     *添加Entry
    */
    void addEntry(int hash, K key, V value, int bucketIndex) {
        //在Entry数组table中获取bucketIndex位置的数据
        Entry<K,V> e = table[bucketIndex];
        //向table数组bucketIndex位置添加Entry对象
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        //调整数组大小
        if (size++ >= threshold)
            resize(2 * table.length);
    }

    /**
     *创建Entry
    */
    void createEntry(int hash, K key, V value, int bucketIndex) {
        //在Entry数组table中获取bucketIndex位置的数据
    Entry<K,V> e = table[bucketIndex];
    //向table数组bucketIndex位置添加Entry对象
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        size++;
    }

addEntry放在put方法添加数据时使用,是根据给定的key、value、hash添加到Entry数组table的bucketIndex位置。要向数组中加数据,这个方法也需要负责resize数组的大小length。当然如果想改变HashMap的put数据的方式,需要重写这个方法。table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
这段代码是向table数组加Entry对象,这个Entry的next指向table数组的bucketIndex位置。
createEntry同addEntry很像,但它只是向数组赋值,不调整大小。在HashMap构造器使用。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HashMap是一种哈希表数据结构,其中每个元素都有一个键和一个值。它使用键的哈希码来确定存储位置,以便快速查找和检索键值对。 HashMap码分析如下: 1. 数据结构 HashMap是一个基于哈希表的实现,内部维护了一个Entry数组,其中每个Entry节点包含了Key-Value键值对,以及指向下一个Entry节点的指针。 2. 哈希算法 HashMap的哈希算法主要包含了以下几个步骤: - 计算哈希码:通过hashCode()方法获取键的哈希码。 - 取模运算:将哈希码与数组长度取模,得到数组下标。 - 处理哈希冲突:如果多个键的哈希码映射到同一个数组下标,就会发生哈希冲突。HashMap使用链表法解决哈希冲突,即将多个Entry节点放在同一个数组下标的链表结构中。 3. 扩容机制 为了避免哈希冲突过多,导致链表过长而影响HashMap的性能,HashMap在达到一定的容量阈值时会自动扩容。扩容时会创建一个新的Entry数组,将原数组中的元素重新哈希并存放到新数组中。 4. 并发控制 HashMap是非线程安全的,因此在多线程环境下需要采取一些措施来保证并发性。HashMap提供了两种线程安全的实现方式:ConcurrentHashMap和Collections.synchronizedMap()。 5. 性能优化 为了提高HashMap的性能,Java 8引入了红黑树的优化机制。当链表长度超过一定阈值时,会将链表转化为红黑树,从而提高查找效率。 总体来说,HashMap是一个高效的数据结构,适用于存储大量的键值对,并且具有快速查找和检索的特点。但是在多线程环境下需要注意并发控制,以及避免哈希冲突过多导致性能下降。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值