C# Hash List<Model>去重问题

关于自定义比较List的指定的部分属性,进行去重,对Hash了解的比较少,这个方法稳定可靠吗,17*23起什么作用呢

public class EntityModelComparer : IEqualityComparer<FileEventModel>
{
    public bool Equals(FileEventModel x,FileEventModely)
    {
        // 根据需要去重的属性进行比较
        return x.FileName == y.FileName &&
               x.CreateTime == y.CreateTime &&
               x.ModifyTime == y.ModifyTime;
    }

    public int GetHashCode(FileEventModel obj)
    {
        // 根据所有需要比较的属性生成哈希码
        int hash = 17;
        hash = hash * 23 + obj.FileName.GetHashCode();
        hash = hash * 23 + obj.CreateTime.GetHashCode();
        hash = hash * 23 + obj.ModifyTime.GetHashCode();
        return hash;
    }
}

可靠!绝对可靠!
事实上只要Equals方法没问题,无论GetHashCode怎么写,哪怕返回一个常数,你的程序也不会有问题,只是效率会比较差。
Hash有种翻译叫散列,步骤大致如下:
存储过程:
1、获取对象Hash值,据此为对象寻找一个内存位置;
2、如果该位置没有对象,存储之;
3、如果该位置有对象,(注意,不同对象可能有相同Hash值,导致位置被占用,再判断是否相等),且与要存储的对象相等,无需操作。
4、如果该位置有对象,且与要存储的对象不相等,寻找相邻位置,进入步骤2。
读取过程:
1、获取对象Hash值,找到Hash值位置的对象;
2、如果有对象,判断是否相等,如相等直接返回;不相等则选择相邻位置,直到找到;或找到未存储对象的位置,即找不到;

所以Hash一定要够‘散’,尽量防止出现不同对象占有一个HashCode,具体的做法可以找相关资料,其具体算法与质数有关

可以的,微软这个设计类似跳表。
所以hash是跳跃入口,也就是返回的hash 都一样,直接返回0,也不影响结果,只影响性能。
至于后面那个其实就是普通加权散列,如果玩线性代数,你就当向量特征看都行,倒不必特别纠结。毕竟你问“稳定可靠”,要不要他都“稳定可靠”,加了他只是因为跳表查询更快

【以下回答由 GPT 生成】

答案:

  1. 使用Hash List进行去重的方法是稳定可靠的。根据定义的EntityModelComparer类,它实现了IEqualityComparer接口,并在Equals方法中指定了如何比较两个FileEventModel对象。同时,在GetHashCode方法中根据所有需要比较的属性生成哈希码。这样做可以确保相同的FileEventModel对象具有相同的哈希码,从而能够在Hash List中进行准确的去重操作。

  2. 生成哈希码时使用17乘以23并加上属性的哈希码是为了避免哈希冲突并尽量保持散列性。哈希码的作用是将对象映射到哈希表中,并在哈希表中进行快速查找。在这种实现中,将17乘以23并加上属性的哈希码是为了生成一个较大的哈希码,从而减少哈希冲突的发生。17和23是两个质数,选择质数可以增加哈希算法的散列性,减少哈希冲突的概率,提高哈希表的性能和查找效率。

希望对你有所帮助!


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^