最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分析HashMap 的 JDK 源碼

 更新時間:2020年10月12日 10:29:23   作者:CodingDiary  
這篇文章主要分析了HashMap 的 JDK 源碼,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下

緣由:今天好友拿著下面的代碼,問我為什么 Map.Entry 這個接口沒有實現(xiàn) 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 實現(xiàn)的 entrySet() 方法,然后我們可以查看 HashMap 里 entrySet() 的源碼

從源碼可以看出,這里的返回了一個 EntrySet 對象,但是需要注意的是這個 EntrySetHashMap 里的一個內(nèi)部類,源碼如下:

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();
  }

  public final boolean contains(Object o) {
    if (!(o instanceof Map.Entry))
      return false;
    Map.Entry<?,?> e = (Map.Entry<?,?>) o;
    Object key = e.getKey();
    Node<K,V> candidate = getNode(hash(key), key);
    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<Map.Entry<K,V>> spliterator() {
    return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);
  }

  public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
    Node<K,V>[] 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<K,V> e = tab[i]; e != null; e = e.next)
          action.accept(e);
      }
      if (modCount != mc)
        throw new ConcurrentModificationException();
    }
  }
}

從這里我們是可以看出,這個 EntrySet 其實是封裝的一個 Node 類的實體。也就是說我們的 set 其實就是這個 Node 對象。

2.現(xiàn)在我們來說說這個 Node 對象,Node 對象也是 HashMap 里的一個內(nèi)部類,源碼如下:

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;
  }

  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<K,V> 的實現(xiàn)類,我們可以看到這個 Node 對象實現(xiàn)了 getKey() getValue() 的方法,所以后面調(diào)用的 entry.getKey() 以及 entry.getValue() 方法其實都是調(diào)用的 Node 對象里的getKey()getValue() 方法,這里就是 Java 的多態(tài)的一種表現(xiàn)。

3.至此,打完收槍!

以上就是分析HashMap 的 JDK 源碼的詳細(xì)內(nèi)容,更多關(guān)于HashMap 的 JDK 源碼的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 解析java基本數(shù)據(jù)類型傳遞與引用傳遞區(qū)別

    解析java基本數(shù)據(jù)類型傳遞與引用傳遞區(qū)別

    這篇文章主要介紹了java基本數(shù)據(jù)類型傳遞與引用傳遞區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • springboot+websocket+redis搭建的實現(xiàn)

    springboot+websocket+redis搭建的實現(xiàn)

    這篇文章主要介紹了springboot+websocket+redis搭建的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Spring攔截器HandlerInterceptor接口代碼解析

    Spring攔截器HandlerInterceptor接口代碼解析

    這篇文章主要介紹了Spring攔截器HandlerInterceptor接口代碼解析,具有一定借鑒價值,需要的朋友可以參考下
    2017-12-12
  • 冒泡排序算法原理及JAVA實現(xiàn)代碼

    冒泡排序算法原理及JAVA實現(xiàn)代碼

    關(guān)鍵字較小的記錄好比氣泡逐趟上浮,關(guān)鍵字較大的記錄好比石塊下沉,每趟有一塊最大的石塊沉底
    2014-01-01
  • Ajax 驗證用戶輸入的驗證碼是否與隨機生成的一致

    Ajax 驗證用戶輸入的驗證碼是否與隨機生成的一致

    本文主要介紹了后臺驗證用戶輸入的驗證碼是否與隨機生成的驗證碼一致的方法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • Idea中添加Maven項目支持scala的詳細(xì)步驟

    Idea中添加Maven項目支持scala的詳細(xì)步驟

    這篇文章主要介紹了Idea中添加Maven項目支持scala,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • Java按時間梯度實現(xiàn)異步回調(diào)接口的方法

    Java按時間梯度實現(xiàn)異步回調(diào)接口的方法

    這篇文章主要介紹了Java按時間梯度實現(xiàn)異步回調(diào)接口,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • java中設(shè)計模式(多例)的實例詳解

    java中設(shè)計模式(多例)的實例詳解

    這篇文章主要介紹了java中設(shè)計模式(多例)的實例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • SpringBoot如何打包自定義生成的包名

    SpringBoot如何打包自定義生成的包名

    這篇文章主要介紹了SpringBoot如何打包自定義生成的包名問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Spring Data中domain模塊的使用

    Spring Data中domain模塊的使用

    Spring Data是一個流行的數(shù)據(jù)訪問框架,本文主要介紹了Spring Data中domain模塊的使用,并展示如何使用它來優(yōu)化我們的數(shù)據(jù)訪問層,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03

最新評論

全南县| 泰和县| 清流县| 灵川县| 驻马店市| 化州市| 农安县| 三河市| 兴业县| 溧水县| 白玉县| 五台县| 郸城县| 横山县| 政和县| 弥渡县| 木兰县| 隆回县| 延长县| 收藏| 平阴县| 阳江市| 师宗县| 石景山区| 巴东县| 湛江市| 沐川县| 龙里县| 容城县| 航空| 寿阳县| 广丰县| 万源市| 望谟县| 屯门区| 梨树县| 博爱县| 枣庄市| 清流县| 桑植县| 宁津县|