日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何理解 ListT和 DictionaryK,V 的扩容机制 ?

發布時間:2023/12/4 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何理解 ListT和 DictionaryK,V 的扩容机制 ? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

咨詢區

  • Royi Namir

為什么 List 是按照 2倍 擴容。

private?void?EnsureCapacity(int?min) {if?(this._items.Length?<?min){int?num?=?(this._items.Length?==?0)???4?:?(this._items.Length?*?2);if?(num?<?min){num?=?min;}this.Capacity?=?num;} }

而 Dictionary<K,V> 是按 素數 擴容。

private?void?Resize() {int?prime?=?HashHelpers.GetPrime(this.count?*?2);int[]?numArray?=?new?int[prime];for?(int?i?=?0;?i?<?numArray.Length;?i++){numArray[i]?=?-1;}Entry<TKey,?TValue>[]?destinationArray?=?new?Entry<TKey,?TValue>[prime];Array.Copy(this.entries,?0,?destinationArray,?0,?this.count);for?(int?j?=?0;?j?<?this.count;?j++){int?index?=?destinationArray[j].hashCode?%?prime;destinationArray[j].next?=?numArray[index];numArray[index]?=?j;}this.buckets?=?numArray;this.entries?=?destinationArray; }

為什么不都按照 2倍 來呢?這樣還可以實現代碼復用。

回答區

  • Gman

Dictionary 是啟發式的,它需要保證 hashcode 必須準均勻的分布在各個桶中,.NET 的 Dictionary 采用的是素數來實現這個均衡,下面是計算桶索引的算法。

int?num?=?this.comparer.GetHashCode(key)?&?2147483647;?//?make?hash?code?positive //?get?the?remainder?from?division?-?that's?our?bucket?index int?num2?=?this.buckets[num?%?((int)this.buckets.Length)];

不過 Java 采用的和 .NET 中的 List 是一樣的擴容機制。

resize(2?*?table.length);

在翻倍之后,java 會重新計算 hashcode 值的。

static?int?hash(int?h)?{//?This?function?ensures?that?hashCodes?that?differ?only?by//?constant?multiples?at?each?bit?position?have?a?bounded//?number?of?collisions?(approximately?8?at?default?load?factor).h?^=?(h?>>>?20)?^?(h?>>>?12);return?h?^?(h?>>>?7)?^?(h?>>>?4); } static?int?indexFor(int?h,?int?length)?{return?h?&?(length-1); }//?from?put()?method int?hash?=?hash(key.hashCode());?//?get?modified?hash int?i?=?indexFor(hash,?table.length);?//?trim?the?hash?to?the?bucket?count

List 不是啟發式的,所以沒有這么煩惱,

點評區

其實說到底,Dictionary采用素數,本質目的就是減少桶掛鏈,減少hashcode沖突,如果掛鏈過長,那就達不到 Contains,Add,Get 等操作的 O(1) 時間復雜度,這也就失去了 Dictionary 原本的特性。

總結

以上是生活随笔為你收集整理的如何理解 ListT和 DictionaryK,V 的扩容机制 ?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。