在给定对象y的情况下,我可以在散列集中检索存储的值x,其中x.Equals(y)

时间:2012-03-29 00:38:46

标签: c# collections

[TestFixture]
class HashSetExample
{
    [Test]
    public void eg()
    {
        var comparer = new OddEvenBag();
        var hs = new HashSet<int>(comparer);

        hs.Add(1);

        Assert.IsTrue(hs.Contains(3));
        Assert.IsFalse(hs.Contains(0));

        // THIS LINE HERE
        var containedValue = hs.First(x => comparer.Equals(x, 3)); // i want something faster than this
        Assert.AreEqual(1, containedValue);
    }

    public class OddEvenBag : IEqualityComparer<int>
    {
        public bool Equals(int x, int y)
        {
            return x % 2 == y % 2;
        }

        public int GetHashCode(int obj)
        {
            return obj % 2;
        }
    }
}

除了检查hs是否包含奇数之外,我想知道如果包含奇数。显然,我想要一种合理扩展的方法,而不是简单地迭代搜索整个集合。

另一种重新解释这个问题的方法是,我想用有效的东西(比如O(1),而不是O(n))替换 THIS LINE HERE 下面的行。

走向何方?我正在尝试实现一个类似于Point3D的 laaaaaaaarge 数量的不可变引用对象。似乎使用HashSet<Foo>代替Dictionary<Foo,Foo>可以节省大约10%的内存。不,显然这不是游戏改变者,但我认为尝试快速获胜并不会有什么坏处。如果这冒犯了任何人,请道歉。

编辑:Link to similar/identical post由Balazs Tihanyi在评论中提供,放在这里强调。

1 个答案:

答案 0 :(得分:1)

简单的答案是否定的,你不能。

如果要检索对象,则需要使用HashSet。 API中没有任何合适的方法可以满足您的要求。

如果你必须使用Set,那么你可以做的一个优化就是首先进行contains检查,然后只有在Set上迭代,如果contains返回true。你几乎肯定会发现HashMap的额外开销很小(因为它本质上只是另一个对象引用)。​​