在字典中查找条目是基于哈希码的。哈希码是基于下面代码中的物品id的,所以我不应该改变物品id。但我做了一些实验,我改变了项id,并在字典中搜索它,但我得到了KeyNotFoundException。谁能给我解释一下为什么?
class Program
{
public class Point
{
public int Id { get; set; }
public override bool Equals(object obj)
{
return obj is Point point &&
Id == point.Id;
}
public override int GetHashCode()
{
return HashCode.Combine(Id);
}
}
static void Main(string[] args)
{
Point point1 = new Point();
point1.Id = 5;
Point point2 = new Point();
point2.Id = 20;
var dictionary = new Dictionary<Point, string>()
{
{ point1, "Poland" },
{ point2, "Germany" }
};
point1.Id = 999; // here I change id
var point1_hash = point1.GetHashCode(); //1727699806
var dictionary1_hash = dictionary.ElementAt(0).Key.GetHashCode(); //1727699806
var dictionary2_hash = dictionary.ElementAt(1).Key.GetHashCode(); //650208270
string result = dictionary[point1]; //KeyNotFoundException
}
}
在更改point1 id之后,它有1727699806的哈希码,字典中索引为0的元素有相同的哈希码: 1727699806 -那么为什么我有KeyNotFoundException?
发布于 2019-05-12 21:04:41
此答案不正确,但由于技术原因无法删除。请参阅下面Progman的答案。
发布于 2019-05-13 01:03:32
下面是Dictionary<T>
内部的相关source code类:
private int FindEntry(TKey key)
{
if (buckets != null)
{
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next)
{
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
}
}
return -1;
}
如您所见,搜索键是从计算搜索到的键的哈希码开始的。此哈希码确定将搜索匹配条目的存储桶。因此,更改存储在字典中的实体的键以三种不同的方式破坏了键查找算法。
https://stackoverflow.com/questions/56099488
复制相似问题