则使用HashSet和Contains返回TRUE

则使用HashSet和Contains返回TRUE

本文介绍了如果哈希中有一个或多个字段,则使用HashSet和Contains返回TRUE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否可以使用HashSet并使方法 Contains 返回,如果字段之一在给定对象的哈希中,则返回true.

I am wondering if it is possible to use a HashSet and make the method Contains to return true if one of the field is in the hash for a giving object.

这是我想要的例子

static void Main(string[] args)
{
    HashSet<Product> hash = new HashSet<Product>();

    // Since the Id is the same, both products are considered to be the same even if the URI is not the same
    // The opposite is also true.  If the URI is the same, both products are considered to be the same even if the Id is not the same
    Product product1 = new Product("123", "www.test.com/123.html");
    Product product2 = new Product("123", "www.test.com/123.html?lang=en");

    hash.Add(product1);

    if (hash.Contains(product2))
    {
        // I want the method "Contains" to return TRUE because one of the field is in the hash
    }
}

这是产品类的定义

public class Product
{
    public string WebId
    public string Uri

    public Product(string Id, string uri)
    {
        WebId = Id;
        Uri = uri;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof(Product)) return false;
        return Equals((Product)obj);
    }

    public bool Equals(Product obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;

        if (String.Equals(WebId, obj.WebId) || String.Equals(Uri, obj.Uri))
            return true;
        else
            return false;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;

            hash = hash * 23 + WebId.GetHashCode();
            hash = hash * 23 + Uri.GetHashCode();
            return hash;
        }
    }
}

运行程序时,方法 Contains 仅运行 GetHashCode ,而从不运行方法 Equals .因此,方法包含返回FALSE.

When I run my program, the method Contains only runs GetHashCode and never the method Equals. Hence, the method Contains return FALSE.

对于上面的示例,如何使我的HashSet返回TRUE?我应该改用Dictionary并将每个字段添加到字典中吗?

How can I make my HashSet to return TRUE for the example above ? Should I be using a Dictionary instead and add each fields to the dictionary ?

推荐答案

对于两个相等的对象,不能保证您的GetHashCode()实现返回相同的值.因为您只需要匹配,例如WebId.然后,Uri修改哈希码.或相反.除了返回0以外,您无法修复此问题.这将杀死HashSet<> perf,查找将是O(n)而不是O(1).

Your GetHashCode() implementation isn't guaranteed to return the same value for two objects that are equal. Since you only require a match on, say, WebId. The Uri then screws up the hash code. Or the other way around. You cannot fix this, other than by returning 0. That's going to kill the HashSet<> perf, lookup will be O(n) instead of O(1).

这篇关于如果哈希中有一个或多个字段,则使用HashSet和Contains返回TRUE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 15:24