分析HashMap 的 JDK 源码

网友投稿 684 2023-03-26

分析HashMap 的 JDK 源码

分析HashMap 的 JDK 源码

缘由:今天好友拿着下面的代码,问我为什么 Map.Entry 这个接口没有实现 getKey() 和 getValue() 方法,却可以使用,由此,开启了一番查阅 JDK 源码的旅途….

Map map = new HashMap();

map.put(1, "张三");

map.put(2, "李四");

map.put(3, "王五");

map.put(4, "赵六");

map.put(5, "钱七");

Set set = map.entrySet();

for (Object object : set) {

Map.Entry entry = (Map.Entry) object;

System.out.println(entry.getKey() + "-->" + entry.getValue());

}

1.首先,我们看 map 对象,这个 map 对象是 HashMap 的一个实例,然后下面的 Set set = map.entrySet(); 可以知道这其实用的 HashMap 实现的 entrySet() 方法,然后我们可以查看 HashMap 里 entrySet() 的源码

从源码可以看出,这里的返回了一个 EntrySet 对象,但是需要注意的是这个 EntrySet 是 HashMap 里的一个内部类,源码如下:

final class EntrySet extends AbstractSet> {

public final int size() {

return size;

}

public final void clear() {

HashMap.this.clear();

}

pueEpPqRblic final Iterator> iterator() {

return new EntryIterator();

}

public final boolean contains(Object o) {

if (!(o instanceof Map.Entry))

return false;

Map.Entry,?> e = (Map.Entry,?>) o;

Object key = e.getKey();

Node

return candidate != null && candidate.equals(e);

}

public final boolean remove(Object o) {

if (o instanceof Map.Entry) {

Map.Entry,?> e = (Map.Entry,?>) o;

Object key = e.getKey();

Object value = e.getValue();

return removeNode(hash(key), key, value, true, true) != null;

}

return false;

}

public final Spliterator> spliterator() {

return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);

}

public final void forEach(Consumer super Map.Entry> action) {

Node[] tab;

if (action == null)

throw new NullPointerException();

if (size > 0 && (tab = table) != null) {

int mc = modCount;

for (int i = 0; i < tab.length; ++i) {

for (Node e = tab[i]; e != null; e = e.next)

action.accept(e);

}

if (modCount != mc)

throw new ConcurrentModificationException();

}

}

}

从这里我们是可以看出,这个 EntrySet 其实是封装的一个 Node 类的实体。也就是说我们的 set 其实就是这个 Node 对象。

2.现在我们来说说这个 Node 对象,Node 对象也是 HashMap 里的一个内部类,源码如下:

static class Node implements Map.Entry {

final int hash;

final K key;

V value;

Node next;

Node(int hash, K key, V value, Node next) {

this.hash = hash;

this.key = key;

this.value = value;

this.next http://= next;

}

public final K getKey() {

return key;

}

public final V getValue() {

return value;

}

public final String toString() {

return key + "=" + value;

}

public final int hashCode() {

return Objects.hashCode(key) ^ Objects.hashCode(value);

}

public final V setValue(V newValue) {

V oldValue = value;

value = newValue;

return oldValue;

}

public final boolean equals(Object o) {

if (o == this)

return true;

if (o instanceof Map.Entry) {

Map.Entry,?> e = (Map.Entry,?>)o;

if (Objects.equals(key, e.getKey()) &&

Objects.equals(value, e.getValue()))

return true;

}

return false;

}

}

可以看出来,这个 Node 对象是 Map.Entry 的实现类,我们可以看到这个 Node 对象实现了 getKey() 和 getValue() 的方法,所以后面调用的 entry.getKey() 以及 entry.getValue() 方法其实都是调用的 Node 对象里的getKey() 和 getValue() 方法,这里就是 java 的多态的一种表现。

3.至此,打完收枪!

以上就是分析HashMap 的 JDK 源码的详细内容,更多关于HashMap 的 JDK 源码的资料请关注我们其它相关文章!

return candidate != null && candidate.equals(e);

}

public final boolean remove(Object o) {

if (o instanceof Map.Entry) {

Map.Entry,?> e = (Map.Entry,?>) o;

Object key = e.getKey();

Object value = e.getValue();

return removeNode(hash(key), key, value, true, true) != null;

}

return false;

}

public final Spliterator> spliterator() {

return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);

}

public final void forEach(Consumer super Map.Entry> action) {

Node[] tab;

if (action == null)

throw new NullPointerException();

if (size > 0 && (tab = table) != null) {

int mc = modCount;

for (int i = 0; i < tab.length; ++i) {

for (Node e = tab[i]; e != null; e = e.next)

action.accept(e);

}

if (modCount != mc)

throw new ConcurrentModificationException();

}

}

}

从这里我们是可以看出,这个 EntrySet 其实是封装的一个 Node 类的实体。也就是说我们的 set 其实就是这个 Node 对象。

2.现在我们来说说这个 Node 对象,Node 对象也是 HashMap 里的一个内部类,源码如下:

static class Node implements Map.Entry {

final int hash;

final K key;

V value;

Node next;

Node(int hash, K key, V value, Node next) {

this.hash = hash;

this.key = key;

this.value = value;

this.next http://= next;

}

public final K getKey() {

return key;

}

public final V getValue() {

return value;

}

public final String toString() {

return key + "=" + value;

}

public final int hashCode() {

return Objects.hashCode(key) ^ Objects.hashCode(value);

}

public final V setValue(V newValue) {

V oldValue = value;

value = newValue;

return oldValue;

}

public final boolean equals(Object o) {

if (o == this)

return true;

if (o instanceof Map.Entry) {

Map.Entry,?> e = (Map.Entry,?>)o;

if (Objects.equals(key, e.getKey()) &&

Objects.equals(value, e.getValue()))

return true;

}

return false;

}

}

可以看出来,这个 Node 对象是 Map.Entry 的实现类,我们可以看到这个 Node 对象实现了 getKey() 和 getValue() 的方法,所以后面调用的 entry.getKey() 以及 entry.getValue() 方法其实都是调用的 Node 对象里的getKey() 和 getValue() 方法,这里就是 java 的多态的一种表现。

3.至此,打完收枪!

以上就是分析HashMap 的 JDK 源码的详细内容,更多关于HashMap 的 JDK 源码的资料请关注我们其它相关文章!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Gradle相对于Maven有哪些优点
下一篇:app跳转小程序(APP跳转小程序)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~