使用HashSet按ID查询Person能否实现O(1)?当前实现是否正确?
问题解答
1. 当前GetPerson方法无法实现O(1)性能
你写的FirstOrDefault(x => x.Id == paramIdPersonToDelete)是遍历整个HashSet做线性查找,时间复杂度为O(n),完全没利用HashSet的哈希优化特性,达不到预期的O(1)性能。
要实现O(1)的查找效率,得用HashSet的TryGetValue方法——它依赖哈希码快速定位元素。具体做法是构造一个仅包含目标ID的Person“占位实例”,用它去HashSet里匹配:
public Person GetPerson(long paramIdPersonToDelete) { var placeholder = new Person { Id = paramIdPersonToDelete }; _myHashset.TryGetValue(placeholder, out var foundPerson); return foundPerson; }
2. Person类的Equals方法存在bug
你的Equals方法里把obj强制转换成Entity了,但你的类是Person,这会导致类型转换异常,应该改成:
// 错误代码 Entity item = (Entity)obj; // 修正后 Person item = (Person)obj;
另外还有两个语法错误要修正:public Class Person应该是public class Person,Name string应该是string Name,否则代码无法编译通过。
3. HashSet的比较逻辑:GetHashCode和Equals缺一不可
HashSet的元素匹配逻辑分两步:
- 先调用
GetHashCode()计算哈希值,快速定位到对应的哈希桶(这是O(1)性能的核心) - 再在哈希桶内调用
Equals()方法,逐一比较元素,确认是否真正相等
只有当两个元素的GetHashCode()返回值相同,且Equals()返回true时,HashSet才会认为它们是同一个元素。
你的Person类里的哈希和相等性实现逻辑是合理的(除了上面的bug):非临时对象(Id不为默认值)的哈希码基于Id生成,Equals方法也只比较Id,符合HashSet的要求。
内容的提问来源于stack exchange,提问作者Álvaro García
相关产品推荐
相关产品推荐

