HashSet<T>
可以在O(1)中确定它是否包含某个项目。如果我在我的自定义类上覆盖Equals()
和GetHashCode()
,我可以拥有一个对象A和另一个不的对象A',但是{{1} } return Equals()
和true
返回相同的哈希码。
现在,假设A在哈希集中,我想在给定A'的O(1)中检索A(从哈希集的角度看它等于A)。
GetHashCode()
怎么做?
(请注意,this没有我想要的答案,this根本没有答案。)
一些背景信息:我想使用set intern 我自己的对象,就像C#interns strings一样:等于对象只需要一个实例。通过这种方式,我可以将元数据附加到这样的对象,并确保在没有该元数据的情况下没有其他任何相同的实例。
答案 0 :(得分:7)
HashSet
上没有任何方法可以满足您的需求。
您可以改为使用Dictionary
:
var dict = new Dictionary<MyClass, MyClass>();
dict[a] = a;
Debug.Assert(dict.ContainsKey(a_prime));
var retrieved_a = dict[a_prime];
答案 1 :(得分:1)
如果我没记错的话,Dictionary
没有基本集合操作的恒定时间实现,而HashSet
具有。{1}}。这是一种使用恒定时间相等查找来实现它的方法,而不会增加HashSet的其他复杂性。如果你需要抓住许多随机元素,使用这种方法至关重要。我在下面写的是Java语法,因为我不知道C#,但这个想法与语言无关。
class MySet<A> {
ArrayList<A> contents = new ArrayList();
HashMap<A,Integer> indices = new HashMap<A,Integer>();
//selects equal element in constant time
A equalElement(A input) {
return contents.get(indices.get(input));
}
//adds new element in constant time
void add(A a) {
indices.put(a,contents.size());
contents.add(a);
}
//removes element in constant time
void remove(A a) {
int index = indices.get(a);
contents.set(index,contents.get(contents.size()-1));
contents.remove(contents.size()-1);
indices.set(contents.get(contents.size()-1),index);
indices.remove(a);
}
//all other operations (contains(), ...) are those from indices.keySet()
}
答案 2 :(得分:0)
使用HashSet.TryGetValue
。 (从.NET Framework 4.7.2开始。)