jdk1.8 hashMap是如何来维护entrySet的

1.经过翻看hashMap的源码,发现并没有主动地去维护entrySet,比如put的时候去存值或者调用entrySet()去维护值,那entryset的值从哪而来呢?

2.hashMap源码

public Set<Map.Entry<K,V>> entrySet() {
        Set<Map.Entry<K,V>> es;
        return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
    }
final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
        public final int size()                 { return size; }
        public final void clear()               { HashMap.this.clear(); }
        public final Iterator<Map.Entry<K,V>> iterator() {
            return new EntryIterator();
        }
    }

3.本人的测试例子:

        Map map = new HashMap();
        map.put(1, 1);
        map.put(2, 2);
        Set set = map.entrySet();
        Iterator iterator = set.iterator();

debug发现这个时候set已经有值了,很是费解。iterator也在调用next方法之前就能看到值。

//iterator源码
public final Iterator<Map.Entry<K,V>> iterator() {
            return new EntryIterator();
        }
 final class EntryIterator extends HashIterator
        implements Iterator<Map.Entry<K,V>> {
        public final Map.Entry<K,V> next() { return nextNode(); }
    }

4.感觉自己说的好混乱,再来阐述一遍问题,entrySet还有它的iterator是怎么维护的?

阅读 6.7k
4 个回答

我看了一下,理解如下

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

当你调用这个方法时

clipboard.png
会初始化一个 EntrySet。

public final Iterator<Map.Entry<K,V>> iterator() {
            return new EntryIterator();
        }

你调用 iterator()时会初始化一个 EntryIterator。

  final class EntryIterator extends HashIterator
        implements Iterator<Map.Entry<K,V>> {
        public final Map.Entry<K,V> next() { return nextNode(); }
    }

这个 EntryIterator 是直接调用的 HashMap.HashIterator.nextNode()
初始化 EntryIterator 时会初识化其父类 HashIterator

   HashIterator() {
            expectedModCount = modCount;
            Node<K,V>[] t = table;//这里会存储相关的数据
            current = next = null;
            index = 0;
            if (t != null && size > 0) { // advance to first entry
                do {} while (index < t.length && (next = t[index++]) == null);
            }
        }

clipboard.png
put的时候会向这个 table 中维护,所以不需要维护 EntrySet 因为它本身不需要存储数据

图片描述

clipboard.png
jdk1.8.0_101 在执行iterator()之前,set就有值了

new HashMap<>()的时候 entrySet就已经不为null了 不知道是不是底层赋值的?

新手上路,请多包涵

因为idea会私自调用对象的toString方法而不会告知,最终会调用java.util.AbstractMap#toString,在这个toString方法会调用entrySet()方法,因为断点会一直走,就会一直调用,导致entrySet值一直在被更新,我起初也非常疑惑,idea坑啊

https://blog.csdn.net/lkforce...
https://www.jianshu.com/p/618...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏