java容器之Map介面

2021-06-21 08:01:25 字數 4386 閱讀 8076

hashmap類

在介紹hashmap之前,有必要介紹下關於雜湊表的知識。(太久沒用到雜湊表,沒想到一時竟然忘記了它的存在的意義了,看來不多做筆記真不行)

雜湊表:支援以常數時間對任何命名項的檢索或刪除。為什麼能夠這麼會有這種效果呢?原理是:定義乙個空的tablesize大小陣列,每個要插入元素根據雜湊函式取得陣列的下標,所以要能根據元素進行線性的檢索;

衝突:就是不同的項通過雜湊函式取得相同的下標(專業術語:相撞),就會造成衝突,我們可以通過線性探測,二次探測等方法來獲得新的下標,也可以用hashmap類中的解決方案,如果出現不同的項有相同的下標,將第二項掛在第一項下,(就是第一項的next指向第二項)依次類推;

但是雜湊表犧牲了元素插入的有序性;

hashmap簡單介紹:

hashmap是基於雜湊表的原理,類中定義了變數table陣列來存放資料,陣列型別為entry型別,(entry是hashmap的乙個靜態內部類);包含這些基本的元素,capacity(容量),loadfactor(載入因子),size,threshold;capacity:即陣列的長度(初始值為16),loadfactor來決定threshold的大小(預設為0.75),threshold = loadfactor* capacity;也就是說如果size>=threshold,那麼我們需要擴充陣列的大小capacity,如果此時的capacity的大小已經達到最大值integer.max_value,那麼不需改變資料大小,繼續新增陣列即可;

每組資料,對應乙個entry類和乙個table的下標,這個小標的取值跟key的hash值和table的長度有關;所以有一點特別重要,在擴充陣列的時候,定義了乙個新的陣列後,由於table的長度變化,需要對每乙個entry物件重新計算小標值,重新將資料填入陣列中;

hashmap的實現不是同步的。

它的部分源**如下:我們一一分析:

//繼承類abstractmap和介面map,cloneable,serializable;

public class hashmapextends abstractmapimplements map, cloneable, serializable

類包含的成員

//雜湊表

static final entry<?,?> empty_table = {};

transient entry table = (entry) empty_table;

//元素的個數

transient int size;

//載入因子,就是說如果要存放size=4的資料,根據載入因子,我們定義雜湊表的大小為4/loadfactor;

//載入因子的預設值是0.75

final float loadfactor;

//值為 (capacity * load factor).

int threshold;

存放一組元素的操作如下:

//向map裡頭存放資料

public v put(k key, v value)

//允許key為空,此時的陣列下標為0,(剩下的)操作相同;

if (key == null)

return putfornullkey(value);

int hash = hash(key);

int i = indexfor(hash, table.length);

//這段**是重點,告訴我們雜湊表存數的形式,找到下標後,判斷該位置是否已經有資料,如果有掛載在已有的資料下;

for (entrye = table[i]; e != null; e = e.next)

}modcount++;

//該方法,將這組資料建立乙個entry物件儲存,同時存放了hash值和小標值,當然要先判斷是否陣列達到了上限,具體請看方法的內容

addentry(hash, key, value, i);

return null;

}void addentry(int hash, k key, v value, int bucketindex)

createentry(hash, key, value, bucketindex);

}//新建乙個entry物件,然後存放在table中

void createentry(int hash, k key, v value, int bucketindex)

接下來,是時候介紹小entry類了,其實它僅僅就是用來存放一組資料和一些基本資訊的結構而已哈;

//內部類 entry,繼承介面map.entry,簡化了部分**

static class entryimplements map.entry

public final k getkey()

public final v getvalue()

public final v setvalue(v newvalue)

}

接下來介紹下,如果根據key來取得value值,知道原理後,我們應該知道怎麼取值了吧,由key獲得hash值,在與table.length計算出下標,從該位置上找出key對應的value。

public v get(object key) 

final entrygetentry(object key)

int hash = (key == null) ? 0 : hash(key);

for (entrye = table[indexfor(hash, table.length)];

e != null;

e = e.next)

return null;

}

listh

ashmap類

簡單的介紹:

linkedhashmap繼承類hashmap,在hashmap的基礎上提供了記錄輸入順序的方法,也就是用鍊錶的方式,對每一次輸入進行記錄;

//定義了成員變數,記錄鍊錶的頭部

private transient entryheader;

//覆蓋了hashmap的init()的方法,原本在hashmap中它是乙個空方法,但是在第一次初始化陣列的時候會被呼叫;

@override

void init()

//當陣列需要調整大小的時候,會呼叫這個方法,(覆蓋的原因僅僅是因為用鍊錶來遍歷效率更高一點哈)

@override

void transfer(hashmap.entry newtable, boolean rehash)

}

//這是listhashmap中類entry乙個方法,當插入新資料的時候會呼叫該方法,此方法在hashmap. entry類中是乙個空的方法;在此,該方法是為了維護資料的有序性

void recordaccess(hashmapm) 

}

treemap

treemap是基於紅黑樹實現的,紅黑樹的具體分析在以後的章節會詳細介紹,現在大致說下紅黑樹的特點:

二叉查詢樹特點:1,父節點的值大於兩個兒子的值;2,同乙個父親,右兒子的值大於左兒子的值;二叉查詢樹有個明顯的缺陷,就是不斷的操作最終會導致樹非常不平衡(也就是樹的左右孩子的深度不一樣),所以誕生了平衡二叉樹,但是平衡二叉樹對樹的要求比較高;由此產生了紅黑樹;對於紅黑樹的操作的時間複雜度,構造樹的方法,以後再詳細介紹;

針對treemap分析:

類成員變數

private final comparator<? super k> comparator;

private transient entryroot = null;

建構函式:

//如果不傳入引數,則預設按照自然順序(就是hashcode的大小)排序

public treemap()

public treemap(comparator<? super k> comparator)

如果compare後,返回0那麼認為這兩個數是一樣的,在treemap中對同樣的數,覆蓋原則哈,

測試**

public class person1			

public static void main(string args) }

class personcomparator implements comparatorelse if(o1.height>o2.height)else }

}

測試結果如下:

p2p2p3

JAVA 集合之Map介面

map介面 集合框架中的另乙個父介面 map集合 另名為雜湊表 用於儲存一一對應的元素資料,第乙個物件可以作為索引,第二個物件作為值,我們稱之為key value,鍵值對。1 以key value形式進行儲存。2 key與value都必須是引用型別。3 key可以為null。4 key與value是...

c STL容器之map容器

1.map中所有的元素都是pair 2.pair元素中第乙個元素為key,第二個元素為value 3.所有元素都會根據鍵值自動排序 4.map中不允許有重複的鍵,multimap中允許有重複的鍵 優點 可以根據key快速的找到value 一 建構函式 mapmp map const map mp 二...

Java知識 Map介面

1.map介面 實現類 hashmap類 map介面常用方法 方法名說明 object put object key,object val 以 鍵 值對 的方式進行儲存 object get object key 根據鍵返回相關聯的值,如果不存在鍵,返回null object remove obje...