从O(1)</t>中的HashSet <t>获取一个相等的对象

时间:2012-06-06 23:02:04

标签: c# set

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一样:等于对象只需要一个实例。通过这种方式,我可以将元数据附加到这样的对象,并确保在没有该元数据的情况下没有其他任何相同的实例。

3 个答案:

答案 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开始。)