Java常見的底層數據結構,一HashMap的分析爲例子

 

首先:數據結構中有 「數組」和 「鏈表」兩種基本的數據結構.算法

數組:存儲區間是連續的,佔用內存空間比較大。查詢的時候比較方便,增長或者刪除的時候比較緩慢;數組

鏈表:存儲區間是離散的,佔用內存空間比較小。增長或者刪除的時候比較方便,查詢的時候比較緩慢;數據結構

哈希表:結合數組和鏈表的優勢。哈希表的實現由不少種的方法。下面是最爲常見的「拉鍊法」;this

在一個長度爲16的數組中,每一個元素存儲的是一個鏈表的頭結點。通常狀況是經過hash(key)%len得到,也就是元素的key的哈希值對數組長度取模獲得。好比上述哈希表中,12%16=12,28%16=12,108%16=12,140%16=12。因此十二、2八、108以及140都存儲在數組下標爲12的位置。排序

-----------------------------------------------------------------------------------------------------接口

上述是最爲常見的三種數據結構:內存

其中List中有LinkedList,ArrayList,Vector .List是有序的,元素能夠重複的。源碼

--------------------List--------------------------------------------------------------------------------hash

比較經常使用的是ArrayList和LinkedList.table

其中ArrayList的底層結構爲數組:利於查詢,不利於增長或者刪除操做;

LinkedList的底層結構爲鏈表:利於增長或者刪除操做,不利於查詢。

--------------------Set--------------------------------------------------------------------------------

Set經常使用的爲HashSet和TreeSet. Set是無序的,元素不能夠重複的。其中TreeSet在插入元素的時候,有天然排序和本身設置順序。

其中HashSet利用哈希算法來存取元素。

TreeSet底層爲二叉樹的結構。

--------------------Map-------------------------------------------------------------------------

Map經常使用的爲HashMap和TreeMap.

1.HashMap是基於哈希表的Ma接口實現的,以key-value的形式存在。HashMap的底層結構爲「哈希表」。每次建立HashMap的時候就會初始化一個table數組。table的數組中的元素類型爲Entry節點。其中HashMap是如何實現存儲數據的:

實現的源碼爲:

public V put(K key, V value) {
        //當key爲null,調用putForNullKey方法,保存null與table第一個位置中,這是HashMap容許爲null的緣由
        if (key == null)
            return putForNullKey(value);
        //計算key的hash值
        int hash = hash(key.hashCode());                  ------(1)
        //計算key hash 值在 table 數組中的位置
        int i = indexFor(hash, table.length);             ------(2)
        //從i出開始迭代 e,找到 key 保存的位置
        for (Entry<K, V> e = table[i]; e != null; e = e.next) {
            Object k;
            //判斷該條鏈上是否有hash值相同的(key相同)
            //若存在相同,則直接覆蓋value,返回舊value
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;    //舊值 = 新值
                e.value = value;
                e.recordAccess(this);
                return oldValue;     //返回舊值
            }
        }
        //修改次數增長1
        modCount++;
        //將key、value添加至i位置處
        addEntry(hash, key, value, i);
        return null;
    }

首先判斷key值是否爲空,若是不爲空的話,計算key的哈希值,根據哈希值來計算在table數組中的位置。而後迭代該位置上的鏈表連,判斷該條鏈上是否有hash值相同的。;若是哈希值相同則覆蓋之前的value,沒有相同的hash值,則將key-value添加到該條鏈上(則將該節點插入該鏈表的鏈頭)。

2.TreeMap:底層結構爲二叉樹。

相關文章
相關標籤/搜索