亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

基于散列的集合簡析

2019-11-10 17:19:25
字體:
來源:轉載
供稿:網友

HashMap簡析

基于散列的集合中,HashMap應該是用的最多的鍵值對容器,既然用的這么頻繁,我覺得還是很有必要搞清楚原理,而寫出來,思路會更清晰。 先看下簡單的繼承體系: 這里寫圖片描述 從圖上看,繼承體系很簡單,2個標記性接口,然后就是作為Map的功能,很單純。 然后再來看看數據結構圖: 這里寫圖片描述 圖上一個空格就代表一個節點,而每個key-value對都保存在一個節點中,下面的代碼正式HashMap每個節點的數據結構。 static class Entry<K,V> implements Map.Entry<K,V> { final K key; V value; Entry<K,V> next; int hash; } 從數據結構圖判斷,HashMap中肯定維護著一個數組,用來存儲每個節點,現在就有2個問題,如何在數組中定位自己的位置(行話叫:桶),萬一桶被占用了怎么辦? 既然叫HashMap,通過名字大概能夠猜想得出了,是通過hash值來定位的,通過hash算出自己桶的位置,然而位置是有限的,那么通過函數映射(hash與數組長取模)到其中的位置時,必然的會出現沖突,解決沖突辦法,就如同上圖所示,鏈表法。 優化性能的設計 HashMap設計時候需要考慮速度的問題,鏈表連接的越長性能就越差,極端的例子,退化成單鏈表,時間復雜度O(N),這樣就失去了快速訪問的特性。 如果為了速度最快,最好的辦法就是沒有鏈表,既然是通過取模的方式進行定位,要達到最少沖突,肯定需要很長的數組,而數組越長,就越容易浪費。 為了達到理想的效果,又不浪費太多的空間,hashmap使用了一個閥值,當對象的數量達到閥值,才會進行擴容,這樣就能夠保證浪費的空間是在可控的有限范圍內。通過調節閥值,可以使得鏈表的鏈接的節點盡量的少。 如何定義閥值?hashmap中用了負載因子這么個概念,用數組的容量*負載因子作為閥值,默認負載因子是0.75。可以自行調整,但是一般不建議,優化有時候是個很棘手的問題,不成熟的優化是所有罪惡之源,最好的策略就是置之不顧,直到你發現真正需要優化他。

其他集合的分析

基于散列的集合,除了HashMap外,常用的還有HashSet、LinkedHashSet、LinkedHashMap。而這三個都是在HashMap的基礎上進行改造的,只要明白了HashMap的原理,其他的非常容易清楚。 HashSet 我們來簡單分析下,在jdk中的源碼

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable{ static final long serialVersionUID = -5024744406713321676L; PRivate transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object(); /** * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has * default initial capacity (16) and load factor (0.75). */ public HashSet() { map = new HashMap<>();//實例化時,同時實例化HashMap }

上面是摘抄HashSet源碼的一段,發現沒,這是組合,是代理,用hashMap進行代理,下面最后列舉下最常用的功能:

public boolean add(E e) { return map.put(e, PRESENT)==null; //PRESENT為常量 } public Iterator<E> iterator() { return map.keySet().iterator(); }

發了沒,是委托給HashMap的。 LinkedHashMap 估計 應該都知道,它既能擁有hashmap的速度,又能有序遍歷,直接看源碼:

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

發現沒,是繼承自HashMap,可以說,復用了大部分的HashMap功能。 思考 :它是如何在hashmap的基礎上進行改造,使的元素有序? 我們先看下面這幅圖: 這里寫圖片描述 大家應該都知道了,左邊的是hashmap的元素節點,而右邊的正是LinkedHashMap的元素節點。發現多了什么了嗎?2個指針,指向前驅和指向后繼。想下,如果每個元素都能夠知道后面是誰,從頭開始按照順序進行元素遍歷,這個還難嗎?看下面創造節點的代碼:

void createEntry(int hash, K key, V value, int bucketIndex) { HashMap.Entry<K,V> old = table[bucketIndex]; Entry<K,V> e = new Entry<>(hash, key, value, old); table[bucketIndex] = e; e.addBefore(header); size++; } private void addBefore(Entry<K,V> existingEntry) { after = existingEntry; before = existingEntry.before; //取前一個節點,對于header參數來說就是最后一個節點。 before.after = this; after.before = this; }

看見沒,createEntry比hashmap多了一個重定位指針的操作。header節點中保存有第二個和最后一個節點的指針(不懂看上圖),保證有序,只需要把現有最后一個節點的after 指向本節點,就保證新加入的元素是有序,現有最后一個節點可以通過header.before獲取,同時為了下一次新加入節點能正常有序,需要把header的前節點重新地位到新的最后一個節點(也就是說header.before指向新節點)。這樣再通過after指針就能順藤摸瓜,順序遍歷了。 LinkedHashSet 看源碼:

public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {

好像和我們想象的不一樣,不應該是LinkedHashMap嗎?不急繼續看其構造函數

public LinkedHashSet(int initialCapacity) { super(initialCapacity, .75f, true); } HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }

發現沒,HashSet這種構造方法用的是LinkedHashMap,現在還需要寫下去嗎,如同hashset復用hashMap原理一樣。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲免费视频一区二区| 成人免费在线视频网址| 国产成人在线一区二区| 国产亚洲欧洲高清一区| 北条麻妃一区二区三区中文字幕| 日韩女在线观看| 亚洲欧美中文日韩v在线观看| 欧美极品美女电影一区| 精品国产一区二区三区在线观看| 欧美精品18videos性欧美| 91久久精品一区| 国产精品久久久久91| 日韩一中文字幕| 日韩黄色在线免费观看| 国产亚洲欧美日韩美女| 亚洲精品国产拍免费91在线| 亚洲乱码av中文一区二区| 超碰精品一区二区三区乱码| 国产日韩在线亚洲字幕中文| 欧美视频专区一二在线观看| 青青草原成人在线视频| 欧美韩国理论所午夜片917电影| 国产一区二区三区欧美| 亚洲成人激情图| 97超视频免费观看| 国产福利精品视频| 久久偷看各类女兵18女厕嘘嘘| 亚洲欧美一区二区三区四区| 国产精品福利片| 亚洲视频日韩精品| 国产日本欧美一区二区三区| 久久香蕉频线观| 欧美精品在线免费| 91综合免费在线| 成人性生交xxxxx网站| 亚洲欧美综合另类中字| 日韩中文字幕不卡视频| 成人网在线免费看| 97视频在线观看网址| 91欧美精品午夜性色福利在线| 中文字幕免费精品一区| 国产香蕉精品视频一区二区三区| 成人久久一区二区| 欧美激情乱人伦| 亚洲精品www| 久久天天躁狠狠躁夜夜av| 日韩中文综合网| 欧美激情a∨在线视频播放| 欧美视频中文在线看| 欧美最近摘花xxxx摘花| 日韩av片永久免费网站| 在线国产精品播放| 欧美日韩一区二区三区在线免费观看| 狠狠躁夜夜躁久久躁别揉| 欧美日韩国产精品一区二区不卡中文| 欧美亚洲国产视频小说| 九九热最新视频//这里只有精品| 国内自拍欧美激情| 亚洲美女在线看| 欧美丰满少妇xxxxx做受| 国产91在线播放九色快色| 疯狂做受xxxx欧美肥白少妇| 久热精品视频在线免费观看| 91久久精品美女| 久久综合国产精品台湾中文娱乐网| 久久亚洲精品一区二区| 亚洲欧美在线一区二区| 亚洲影视中文字幕| 国产日韩换脸av一区在线观看| 欧美区在线播放| 日韩在线资源网| 亚洲国产精品免费| 国产精品久久久久av免费| 久久91精品国产91久久跳| 国产成人精品亚洲精品| 国产成+人+综合+亚洲欧洲| 中文字幕视频在线免费欧美日韩综合在线看| 91最新国产视频| 欧美日韩一区二区三区| 91精品久久久久久久久中文字幕| 欧美老女人xx| 欧洲成人在线视频| 色青青草原桃花久久综合| 久久av红桃一区二区小说| 欧美日韩国产黄| 亚洲最大的成人网| 在线性视频日韩欧美| 韩日欧美一区二区| 免费91麻豆精品国产自产在线观看| 国产亚洲日本欧美韩国| 国产精品久久久久久久久借妻| 色av中文字幕一区| 国产精品成人v| 午夜精品一区二区三区av| 大伊人狠狠躁夜夜躁av一区| 欧美肥老太性生活视频| 国产精品美女久久久久久免费| 91老司机在线| 中文字幕精品久久久久| 日韩有码视频在线| 国产精品久久久久久一区二区| 2020久久国产精品| 日韩网站免费观看| 一区二区三区无码高清视频| 欧美高清自拍一区| 国产一区二区三区视频在线观看| 日韩欧美国产免费播放| 九色91av视频| 日韩欧美一区二区在线| 久久久这里只有精品视频| 国产精品久久久久9999| 亚洲欧美精品伊人久久| 国产成人在线亚洲欧美| 久久精品最新地址| 欧美人与性动交| 国产精品视频自拍| 亚洲香蕉伊综合在人在线视看| 18性欧美xxxⅹ性满足| 91老司机在线| 亚洲天堂网在线观看| 韩国美女主播一区| 欧美日韩激情视频| 日韩国产高清污视频在线观看| 日韩成人在线免费观看| 日韩电影免费在线观看| 最近2019好看的中文字幕免费| 成人综合国产精品| 精品视频偷偷看在线观看| 国产精品激情av在线播放| 韩日精品中文字幕| 亚洲护士老师的毛茸茸最新章节| 欧美激情视频在线| 中文字幕在线视频日韩| 国产精品一区二区久久| 理论片在线不卡免费观看| 国产精品99一区| 欧美午夜丰满在线18影院| 亚洲香蕉成人av网站在线观看| 国产精品欧美日韩一区二区| 亚洲欧美日韩天堂一区二区| 国产欧美一区二区三区久久| 中文字幕在线看视频国产欧美在线看完整| 亚洲va码欧洲m码| 中文字幕亚洲二区| 精品亚洲夜色av98在线观看| 国产成人精品在线播放| 在线播放日韩精品| 黄色成人av网| 亚洲美女精品久久| 欧美精品18videosex性欧美| 国产91露脸中文字幕在线| 国产欧美日韩中文字幕| 国产区亚洲区欧美区| 国产精品嫩草视频| 国产小视频91| 国产精品pans私拍| 欧美成人中文字幕在线| 2019中文字幕在线观看| 欧美性色视频在线| 久久久精品电影| 欧美性在线视频| 国产一区视频在线播放| 国产精品福利在线观看网址| 日韩av在线最新|