成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java HashMap分析之一:基本結構

開發 后端
Java的HashMap非常的常用,本篇研究它的實現算法,最后希望計算出內存占用,性能的量化數據,然后得出什么時候使用HashMap,什么時候不能濫用的結論。

Java的HashMap非常的常用,本篇研究它的實現算法,***希望計算出內存占用,性能的量化數據,然后得出什么時候使用HashMap,什么時候不能濫用的結論。

HashMap實際上是一個數組,數組里面的每個元素都是一個鏈表。每個元素在通過put方法放入HashMap中的時候,要按照如下步驟進行:

1.根據該元素自身提供的hashcode計算出散列值,該散列值就是數組的下標

2.將新元素放入該數組位置的鏈表中

先來看一下數組的定義:

  1. /**  
  2.      * The table, resized as necessary. Length MUST Always be a power of two.  
  3.      */ 
  4.     transient Entry[] table; 

這是一個數組,transient關鍵字告訴我們它不會參與序列化。既然是一個數組,總有數目上限,也就意味著如果存入HashMap的元素太多,導致數組大小不能夠存放所有的鏈表的時候,數組大小必須要能夠調整。所以首先來考察一下數組容量的相關算法。

***,Entry是什么類型?

  1. static class Entry<K,V> implements Map.Entry<K,V> {  
  2.         final K key;  
  3.         V value;  
  4.         Entry<K,V> next;  
  5.         final int hash;  
  6.  
  7.         /**  
  8.          * Creates new entry.  
  9.          */ 
  10.         Entry(int h, K k, V v, Entry<K,V> n) {  
  11.             value = v;  
  12.             next = n;  
  13.             key = k;  
  14.             hash = h;  
  15.         }  
  16.         ....  
  17.         public final boolean equals(Object o) {  
  18.             if (!(o instanceof Map.Entry))  
  19.                 return false;  
  20.             Map.Entry e = (Map.Entry)o;  
  21.             Object k1 = getKey();  
  22.             Object k2 = e.getKey();  
  23.             if (k1 == k2 || (k1 != null && k1.equals(k2))) {  
  24.                 Object v1 = getValue();  
  25.                 Object v2 = e.getValue();  
  26.                 if (v1 == v2 || (v1 != null && v1.equals(v2)))  
  27.                     return true;  
  28.             }  
  29.             return false;  
  30.         }  
  31.  
  32.         public final int hashCode() {  
  33.             return (key==null   ? 0 : key.hashCode()) ^  
  34.                    (value==null ? 0 : value.hashCode());  
  35.         }  
  36.         .... 

這是一個HashMap類的內部靜態類。實現了Map.Entry接口。接受兩個模板參數K和V。key和hash一旦在構造函數中被初始化,就不可改變,并且由于有next的存在,Entry可以構成一個單向鏈表。

比較重要的是equals和hashCode方法。代碼先列出來,后面再解釋。

第二,初始容量的設定

大多數都在下面的構造函數里面.用于指定的initialCapacity不準小于0,也不能超過***值。并且最終的capicity必須是2的n次方。還有如果使用了無參數的構造函數,默認會創建一個擁有16個元素的數組。

  1. public HashMap(int initialCapacity, float loadFactor) {  
  2.         if (initialCapacity < 0)  
  3.             throw new IllegalArgumentException("Illegal initial capacity: " +  
  4.                                                initialCapacity);  
  5.         if (initialCapacity > MAXIMUM_CAPACITY)  
  6.             initialCapacity = MAXIMUM_CAPACITY;  
  7.         if (loadFactor <= 0 || Float.isNaN(loadFactor))  
  8.             throw new IllegalArgumentException("Illegal load factor: " +  
  9.                                                loadFactor);  
  10.  
  11.         // Find a power of 2 >= initialCapacity  
  12.         int capacity = 1;  
  13.         while (capacity < initialCapacity)  
  14.             capacity <<= 1;  
  15.  
  16.         this.loadFactor = loadFactor;  
  17.         threshold = (int)(capacity * loadFactor);  
  18.         table = new Entry[capacity];  
  19.         init();  
  20.     } 

第三,什么時候應該調整數組的大小?

算法是這樣,有一個變量size保存了實際數組已經使用了多少個元素,并且如果size的值達到了變量threshold的值,就必須擴充數組的容量。threshold=capicity*loadFactor.capicity是數組***的容納元素個數,loadFactor可以在構造函數中制定,否則采用默認值0.75f。capicity的***值是1<<30(也就是2的30次方,1073741824).由此我們可以看到HashMap最多存放10億多個鏈表。

第四,如何調整數組大小?

答案是2倍,很像C++里面的vector的分配策略。

  1. void addEntry(int hash, K key, V value, int bucketIndex) {  
  2.         Entry<K,V> e = table[bucketIndex];  
  3.         table[bucketIndex] = new Entry<K,V>(hash, key, value, e);  
  4.         if (size++ >= threshold)  
  5.             resize(2 * table.length);  
  6.     } 

第五,為什么數組大小必須是2的倍數?

在后面介紹散列值算法的時候會回答。

原文鏈接:http://blog.csdn.net/sheismylife/article/details/7347026

【編輯推薦】

  1. Java集合框架總結:Set接口的使用
  2. Java的位移運算巧方法
  3. Java7的一個新類JLayer:裝飾的Swing組件
  4. 關于Java中內存溢出的解決辦法
  5. Java中的面向對象特性
責任編輯:林師授 來源: sheismylife的博客
相關推薦

2011-04-25 11:18:39

Ajax

2015-08-10 15:12:27

Java實例源碼分析

2021-07-06 06:12:43

Shell語法變量

2016-09-12 14:33:20

javaHashMap

2009-12-21 14:37:14

2012-03-15 17:18:33

JavaHashMap

2012-03-15 16:27:13

JavaHashMap

2021-10-30 18:38:49

Java c++反射

2023-09-12 07:31:45

HashMap線程

2015-07-16 11:27:52

2023-09-14 11:45:24

HashMap散列表

2022-10-27 16:07:24

littlefs存儲結構

2009-12-22 12:54:10

Linux統一設備

2010-06-13 15:16:02

2009-07-09 13:45:06

Servlet基本結構

2011-05-27 13:56:04

網站流量

2011-07-22 13:41:57

java

2023-09-15 08:14:48

HashMap負載因子

2012-06-05 00:41:07

JavaJava內存

2018-04-17 16:29:24

Java面試HTTP
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产中文视频 | 久久久蜜臀国产一区二区 | 国产精品免费在线 | 国产在线97| 亚洲欧美少妇 | 欧美激情国产日韩精品一区18 | 精品久久精品 | 亚洲午夜网 | 亚洲精品视频观看 | 亚洲日本视频 | 国产午夜精品久久久 | 精品国产一区二区三区日日嗨 | 伊人网在线看 | 国产免费一区二区三区网站免费 | 国产美女黄色片 | 久久国产精品免费一区二区三区 | 成人av一区 | 91精品一区二区三区久久久久久 | 亚洲最大的成人网 | 精品一二三区在线观看 | 久久久精品一区二区三区四季av | www.夜夜骑.com | 国产中文在线观看 | 黄色毛片在线看 | 午夜性色a√在线视频观看9 | 欧美日韩综合视频 | 日韩成人影院在线观看 | 亚洲精品乱码久久久久久久久 | 日韩小视频在线 | 日韩精品极品视频在线观看免费 | 日韩成人在线视频 | 天天插天天操 | 99精品久久久| 日本韩国欧美在线观看 | 丁香久久| 国产一区二区三区四区三区四 | 天天曰夜夜操 | 日韩av啪啪网站大全免费观看 | 欧美无乱码久久久免费午夜一区 | av一区二区三区四区 | 欧美成人精品一区二区男人看 |