Java知識 LinkedHashMap詳解

2021-08-08 15:26:05 字數 2760 閱讀 9594

與hashmap的異同:同樣是基於雜湊表實現,區別是,linkedhashmap內部多了乙個雙向迴圈鍊錶的維護,該鍊錶是有序的,可以按元素插入順序或元素最近訪問順序(lru)排列,

簡單地說:linkedhashmap=雜湊表+迴圈雙向鍊錶

首先,hashmap的構造方法都要呼叫乙個方法 init(),而linkedhashmap對這個方法進行了重寫:

public

hashmap(int initialcapacity, float loadfactor)

@override

void init()

如果已經熟悉過hashmap,那麼你一定可以發現,這裡的entry<>已經和hashmap中的entry內部類不一樣了,所以,linkedhashmap重寫了hashmap中最基本的單元entry:

/**

* linkedhashmap entry.

*/private static class

entry

extends

hashmap.entry

private void remove()

private void addbefore(entryexistingentry)

void recordaccess(hashmapm)

}void recordremoval(hashmapm)

}

看到這段內部類的**,我們可以總結出兩個重要的特性:

(1)這裡的 before 和 after 是增加的。此處的entry它繼承了hashmap.entry,所以它的成員變數有:

hash值(這個容易被忽略)

key 和 value 兩個變數

用於維護雜湊表的 next

用於維護雙向迴圈鍊錶的 before 和 after

(2)linkedhashmap中依然在使用 【桶+鍊錶】 的典型雜湊表結構。這一點從它復用的hashmap中的**可以看出。所以,它依然會有resize,使用的是鍊錶來維護順序,所以,resize並不會破壞這個順序的維護。

private final boolean accessorder;

accessorder:true則按照lru演算法迭代整個linkedhashmap,false則按照元素的插入順序迭代!

最後兩個圖是精髓,訪問就是先刪除後新增到尾部。

迴圈雙向鍊錶的頭部存放的是最久訪問的節點或最先插入的節點,尾部為最近訪問的或最近插入的節點

如果上圖太簡單的話,下面有個例子還是不錯的:

public static void main(string args) 

system.out

.println("**** 初始順序:****");

for (map.entry

entry : lmap.entryset())

// 依次訪問8,1,4,7,3

lmap.get(8);

lmap.get(1);

lmap.get(4);

lmap.get(7);

lmap.get(3);

system.out

.println("\n\n**** 訪問過後的順序:****");

for (map.entry

entry : lmap.entryset())

// put 新值

lmap.put(11, "@" + 11);

lmap.put(12, "@" + 12);

lmap.put(13, "@" + 13);

system.out

.println("\n\n**** 插入新k-v後的順序:****");

for (map.entry

entry : lmap.entryset())

// put 舊值

lmap.put(0, "new" + 0);

lmap.put(2, "new" + 2);

lmap.put(4, "new" + 4);

system.out

.println("\n\n**** 插入舊k後的順序:****");

for (map.entry

entry : lmap.entryset())

}

output:

**** 初始順序:****

@0@1

@2@3

@4@5

@6@7

@8@9

**** 訪問過後的順序:****

@0@2

@5@6

@9@8

@1@4

@7@3

**** 插入新k-v後的順序:****

@0@2

@5@6

@9@8

@1@4

@7@3

@11@12

@13

**** 插入舊k後的順序:****

@5@6

@9@8

@1@7

@3@11

@12@13 new0 new2 new4

實現的原理就是,每次get的時候,將這個元素移到佇列的末尾,從而,最不常訪問的元素在佇列的首部。

參考資料:

Java知識學習

讀取檔案裡面的內容,直接讀取不就得了,但是我看到很多人都要乙個位元組陣列,例如 byte b new byte 1024 然後再讀取 b裡面的內容,像下面這樣 fileinputstream in new fileinputstream e lyrics.txt byte b new byte 10...

java 知識蒐集

我們都知道instanceof測試乙個例項是不是乙個類的例項。那麼如果你認為乙個dog 的dog instanceof object 會返回假,那你就大錯特錯了。對於所有的父類 super 類,instanceof 測試都會返回真。我們來看這個例子 class base class ext1 ext...

java知識總結

包的訪問控制 子類 同個包內 不同包內 public y y y protect y y n private n n n i o和流 四個抽象類 讀寫位元組 inputstream outputstream 讀寫unicode字元 reader writer iterator arraylist v...