在.NET中,Dictionary<TKey, TValue>
有一个构造函数,它带有一个参数int capacity
。这与许多其他集合相同,例如List<T>
,Queue<T>
和Stack<T>
;此外,根据the MSDN documentation:
Dictionary的容量是在需要调整大小之前可以添加到Dictionary的元素数。当元素添加到Dictionary时,通过重新分配内部数组,容量会根据需要自动增加。
这对我来说与List<T>
等其他集合几乎相同。由于这些集合在必要时具有自动调整大小的行为,因此可能具有比所需更大的容量,其中大多数都具有一个TrimExcess
方法。如果您一次向集合中添加未知数量的项目,那么这将非常方便,之后您将不会添加任何其他项目。
为什么Dictionary<TKey, TValue>
没有相同的TrimExcess
方法?
(免责声明:我非常熟悉“默认情况下不存在的功能”响应;我想我大多只是想知道TrimExcess
Dictionary
的{{1}}是否存在特殊原因没有意义,或者为什么它比List
这样的简单集合更难实现。)
答案 0 :(得分:6)
我猜在这种情况下,capacity参数有助于定义散列函数以及桶的数量;调整稀疏数据集的大小/修整将需要重新计算剩余的所有存储项的哈希值。
答案 1 :(得分:5)
这是部分猜测:字典被“排序”为哈希表。保留的容量不仅仅是字典顶部的一堆空闲内存地址。相反,它包含整个字典中的空房间。这样做是为了使添加/移动/移除等非常有效。如果您对Dictionary有TrimExcess
方法,则整个Dictionary必须将所有内容复制到新位置,而且元素之间没有任何间隙。
实际上:差距应保持不变,否则哈希表的好处将变为无效,修剪(TrimExcess
),如果实施,应该只修剪内部ValueCollection
。
更新:扩展并更改了我选择不当的单词
更新: the BCL team says TrimExcess for Dictionaries "could be useful"
更新:功能请求已解决,因为无法修复:“不幸的是,我们无法在下一版本的.NET中找到它,所以我'我解决这个问题并不会解决。“
答案 2 :(得分:4)
每个MSDN Dictionary实现为哈希表。如果你削减了多余的部分,你就必须提出一种算法,该算法仍然提供接近O(1)的查找时间,实际上是一个随机排序的列表。
答案 3 :(得分:1)
实际上我是那个要求微软实施TrimExcess的人。 我已经提交了多篇涉及字典的文章,在所有情况下我都实现了TrimExcess。实际上,当增加或减小桶的大小时,可以调用当桶太小时使用的Resize。
今天我刚发表了另一篇文章,它是一个字典的C ++实现,它支持TrimExcess: http://www.codeproject.com/Articles/761040/A-NET-like-Dictionary-in-Cplusplus
本文中可以找到另一种实现(.NET): http://www.codeproject.com/Articles/548406/Dictionary-plus-Locking-versus-ConcurrentDictionar
答案 4 :(得分:0)
到2019年,.Net Standard 2.1+和.Net Core 2.1+实施Dictionary<TKey, TValue>.TrimExcess()
:
.Net Framework在任何版本中均未实现。