创建对象的唯一 HashSet [重复]

Posted

技术标签:

【中文标题】创建对象的唯一 HashSet [重复]【英文标题】:Create unique HashSet of objects [duplicate] 【发布时间】:2019-09-18 09:58:38 【问题描述】:

我创建了一个 Person 类和一个 HashSet。如果我将同一个人添加到 HashSet,它不知道该 Person 已经存在并且它将多次添加同一个人。我需要覆盖什么函数才能在 HashSet 中只有唯一元素?

public class Person

    public Person(int age, string name)
    
        this.age = age;
        this.name = name;
    

    int age;
    string name;

    public int Age 
        get  return age; 
        set  age = value; 
    

    public string Name 
        get  return name; 
        set  name = value; 
    

    public override bool Equals(object obj)
     
        var other = obj as Person;
        if (other == null) 
            return false;
        

        return age == other.age && name == other.name;
    


void Button1Click(object sender, EventArgs e)

    List<Person> allPeople = new List<Person>();
    Person p = new Person(15, "John");
    allPeople.Add(p);
    p = new Person(22, "Michael");
    allPeople.Add(p);
    p = new Person(16, "Alex");
    allPeople.Add(p);
    p = new Person(22, "Michael");
    allPeople.Add(p);
    p = new Person(15, "John");
    allPeople.Add(p);

    HashSet<Person> hashset = new HashSet<Person>();

    foreach(Person pers in allPeople) 
        hashset.Add(pers);
    

    foreach(Person pers in hashset) 
        listBox1.Items.Add(pers.Name + ", " + pers.Age);
    

【问题讨论】:

你必须覆盖GetHashCode 【参考方案1】:

首先,HashSet 是如何知道 2 个对象相等的。它不仅为此使用“等于”方法。它使用“GetHashCode”方法比较两个对象的HashCode。

因此,您需要做的是覆盖 GetHashCode 并找到某种方法将您的 Person 映射到 int 值。

例如,您可以执行“age + AsciiValue(name)”。

所以你需要做的就是添加

public override int GetHashCode()

    return age + AsciiValue(name); //i will leave the ascii value implementation to you

到您的人员类,并且重复的人员不应再存在于同一个 HashSet 中

OP 的实现:

int AsciiCode(string str)  
    int sum = 0;
    int len = str.Length;
    for(int i = 0; i < len; i++) 
        sum += str[i] * Convert.ToInt32(Math.Pow(2, i));
        sum = sum % (Convert.ToInt32(Math.Pow(2, 31) - 1));
     
    return sum;

【讨论】:

第一句不正确。 HashSet 确实使用 equals,但只有在它确认哈希码相同之后。可能有两个不相等但具有相同哈希码的对象。 等一下,再检查一下句子。对我来说它看起来没有错。它不仅使用等于 是的,对不起。我被全大写弄糊涂了,以后不要错过微小的“唯一”。也许改写句子以减少混乱。 谢谢,我将 name 中字符的 ASCII 码乘以 2^position 并返回一些大的模数。 int AsciiCode(string str) int sum = 0; int len = str.Length; for(int i = 0; i

以上是关于创建对象的唯一 HashSet [重复]的主要内容,如果未能解决你的问题,请参考以下文章

第1章 HashSet集合

HashSet

基于对象的某些属性创建唯一的哈希码[重复]

arrayList 和hashSet的区别

java:Set对象TreeSet有序子类,HashSet无序子类,重复对象二

类HashSet