HashMap源码学习第三天

13,转换成 Set/CollectionkeySet()

14,获得 value 集合values()

15,获得 key-value Se entrySet()

16,清空clear()

17,序列化writeObject(ObjectOutputStream s)

18,反序列化readObject(ObjectInputStream s)

19,克隆clone()


13,转换成 Set/CollectionkeySet()

keySet() 方法,获得 key Set 。代码如下:

public Set<K> keySet() {
        Set<K> ks = keySet; // 获得 keySet 缓存
        if (ks == null) {  // 如果不存在,则进行创建
            ks = new KeySet();
            keySet = ks;
        }
        return ks;
    }

14,获得 value 集合values()

values() 方法,获得 value 集合。代码如下:

public Collection<V> values() {
        Collection<V> vs = values; // 获得 vs 缓存
        if (vs == null) {
            vs = new Values();  // 如果不存在,则进行创建
            values = vs;
        }
        return vs;
    }

15,获得 key-value Se entrySet()

entrySet() 方法,获得 key-value Set 。代码如下:

public Set<Map.Entry<K,V>> entrySet() {
        Set<Map.Entry<K,V>> es;   // 获得 entrySet 缓存
        return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;  // 如果不存在,则进行创建
    }

16,清空clear()

clear() 方法,清空 HashMap 。代码如下:

public void clear() {
        Node<K,V>[] tab;
        modCount++;   // 增加修改次数
        if ((tab = table) != null && size > 0) {
            size = 0;  // 设置大小为 0
            for (int i = 0; i < tab.length; ++i)
                tab[i] = null; // 设置每个位置为 null
        }
    }

17,序列化writeObject(ObjectOutputStream s)

writeObject(ObjectOutputStream s) 方法,序列化 HashMap 对象。代码如下:

 private void writeObject(java.io.ObjectOutputStream s)
        throws IOException {
        int buckets = capacity();  // 获得 HashMap table 数组大小
        // Write out the threshold, loadfactor, and any hidden stuff
        s.defaultWriteObject();  // 写入非静态属性、非 transient 属性
        s.writeInt(buckets);  // 写入 table 数组大小
        s.writeInt(size);  // 写入 key-value 键值对数量
        internalWriteEntries(s);  // 写入具体的 key-value 键值对
    }


 final int capacity() {  // table 数组大小。封装方法的原因,需要考虑 table 未初始化的情况。
        return (table != null) ? table.length :
            (threshold > 0) ? threshold :
            DEFAULT_INITIAL_CAPACITY;
    }


void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
        Node<K,V>[] tab;
        if (size > 0 && (tab = table) != null) {
            for (int i = 0; i < tab.length; ++i) {  // 遍历 table 数组
                for (Node<K,V> e = tab[i]; e != null; e = e.next) {  // 遍历链表或红黑树
                    s.writeObject(e.key);
                    s.writeObject(e.value);
                }
            }
        }
    }

18,反序列化readObject(ObjectInputStream s)

readObject(ObjectInputStream s) 方法,反序列化成 HashMap 对象。代码如下:

private void readObject(java.io.ObjectInputStream s)
        throws IOException, ClassNotFoundException {
        // Read in the threshold (ignored), loadfactor, and any hidden stuff// 读取非静态属性、非 transient 属性
        s.defaultReadObject();
        reinitialize();
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new InvalidObjectException("Illegal load factor: " +
                                             loadFactor);
        s.readInt();                // Read and ignore number of buckets
        int mappings = s.readInt(); // Read number of mappings (size)
        if (mappings < 0)
            throw new InvalidObjectException("Illegal mappings count: " +
                                             mappings);
        else if (mappings > 0) { // (if zero, use defaults)
            // Size the table using given load factor only if within
            // range of 0.25...4.0
            float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
            float fc = (float)mappings / lf + 1.0f;
            int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
                       DEFAULT_INITIAL_CAPACITY :
                       (fc >= MAXIMUM_CAPACITY) ?
                       MAXIMUM_CAPACITY :
                       tableSizeFor((int)fc));
            float ft = (float)cap * lf;
            threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
                         (int)ft : Integer.MAX_VALUE);

            // Check Map.Entry[].class since it's the nearest public type to
            // what we're actually creating.
            SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, cap);
            @SuppressWarnings({"rawtypes","unchecked"})
            Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
            table = tab;

            // Read the keys and values, and put the mappings in the HashMap
            for (int i = 0; i < mappings; i++) {
                @SuppressWarnings("unchecked")
                    K key = (K) s.readObject();
                @SuppressWarnings("unchecked")
                    V value = (V) s.readObject();
                putVal(hash(key), key, value, false, false);
            }
        }
    }



void reinitialize() {
        table = null;
        entrySet = null;
        keySet = null;
        values = null;
        modCount = 0;
        threshold = 0;
        size = 0;
    }

19,克隆clone()

clone() 方法,克隆 HashMap 对象。代码如下:

@SuppressWarnings("unchecked")
    @Override
    public Object clone() {
        HashMap<K,V> result; // 克隆 HashMap 对象
        try {
            result = (HashMap<K,V>)super.clone();
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
        result.reinitialize();  // 重新初始化
        result.putMapEntries(this, false); // 批量添加 key-value 键值对到其中
        return result; // 返回 result
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ehdjsbs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值