TDictionary<TKey,TValue>使用一个内部数组,如果已满,则将其加倍:

newCap := Length(FItems) * 2;
if newCap = 0 then
  newCap := 4;
Rehash(newCap);


这对于中等数量的项目效果很好,但是如果达到上限,这是非常不幸的,因为即使有近一半的可用内存,它也会抛出EOutOfMemory异常。

有什么方法可以影响这种行为?其他集合类如何处理这种情况?

最佳答案

您需要了解字典的工作原理。词典包含“哈希存储桶”列表,您插入的项将放置在其中。那是一个有限的数字,所以一旦填满它,就需要分配更多的存储桶,就无法解决它。由于对象到桶的分配是基于哈希函数的结果,因此,您不能简单地将桶添加到数组的末尾并在其中放置内容,您需要重新分配整个块列表,重新哈希所有内容并将其放入相应的(新)存储桶中。

鉴于此行为,使字典一旦满就不重新分配的唯一方法是确保它永远不会满。如果您知道要在字典中插入的项目数,则将其作为参数传递给构造函数,即可完成操作,不再需要重新分配字典。

如果您无法做到这一点(您不知道字典中要包含的项数),则需要重新考虑是什么原因使您首先选择了TDictionary并选择了一个提供以下内容的数据结构:更好地折衷您的特定算法。例如,您可以使用二叉搜索树,因为它们通过轮换现有节点中的信息来进行平衡,而无需重新分配。

07-26 04:05