标签: gethashcode

是否应该在可变类型上为 IEquatable<T> 实现 GetHashCode?

我正在实施IEquatable<T>,但我很难就可变GetHashCode类的覆盖达成共识。

以下资源都提供了一个实现,GetHashCode如果对象发生更改,则在对象的生命周期内将返回不同的值:

但是,此链接指出GetHashCode不应为可变类型实现,因为如果对象是集合的一部分,则可能会导致不良行为(这也一直是我的理解)

有趣的是,MSDN 示例实现了GetHashCode仅使用不可变属性,这符合我的理解。但我很困惑为什么其他资源不涵盖这一点。他们真的错了吗?

如果一个类型根本没有不可变属性,编译器会GetHashCode在我重写时警告该类型丢失Equals(object)。在这种情况下,我应该实现它并只调用base.GetHashCode()或禁用编译器警告,还是我错过了某些内容并且GetHashCode应该始终被覆盖和实现?事实上,如果建议不GetHashCode应该为可变类型实现,为什么还要为不可变类型实现呢?与默认实现相比,它只是为了减少冲突GetHashCode,还是实际上添加了更多有形的功能?

总结我的问题,我的困境是,GetHashCode在可变对象上使用意味着如果对象的属性发生变化,它可以在对象的生命周期内返回不同的值。但不使用它意味着比较可能等效的对象的好处会丢失,因为它将始终返回唯一值,因此集合将始终回退到使用Equals其操作。

输入此问题后,“类似问题”框中弹出了另一个问题,似乎涉及同一主题。答案似乎非常明确,因为在GetHashCode实现中只应使用不可变属性。如果没有,那就干脆不写。Dictionary<TKey, TValue>尽管不是 O(1) 性能,但仍然可以正常运行。

c# mutable immutability iequatable gethashcode

8
推荐指数
1
解决办法
3122
查看次数

我应该如何实现Object.GetHashCode()以实现复杂的相等?

基本上,到目前为止我有以下内容:

class Foo {
    public override bool Equals(object obj)
    {
        Foo d = obj as Foo ;
        if (d == null)
            return false;

        return this.Equals(d);
    }

    #region IEquatable<Foo> Members

    public bool Equals(Foo other)
    {
        if (this.Guid != String.Empty && this.Guid == other.Guid)
            return true;
        else if (this.Guid != String.Empty || other.Guid != String.Empty)
            return false;

        if (this.Title == other.Title &&
            this.PublishDate == other.PublishDate &&
            this.Description == other.Description)
            return true;

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,问题是:我有一个非必需字段Guid,这是一个唯一标识符.如果没有设置,那么我需要尝试根据不太准确的度量确定相等性,以尝试确定两个对象是否相等.这很好用,但它会弄得GetHashCode()一团糟......我应该怎么做呢?一个天真的实现将是这样的:

public override …
Run Code Online (Sandbox Code Playgroud)

c# equals iequatable gethashcode

7
推荐指数
2
解决办法
4473
查看次数

如何选择素数来计算哈希码?

这个问题遵循Jon Skeet在这个问题上给出的答案:" 覆盖System.Object.GetHashCode的最佳算法是什么? ".要计算哈希码,请使用以下算法:

public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = 17;
        // Suitable nullity checks etc, of course :)
        hash = hash * 23 + field1.GetHashCode();
        hash = hash * 23 + field2.GetHashCode();
        hash = hash * 23 + field3.GetHashCode();
        return hash;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么选择数字17和23.我们为什么不选3和5?这也是素数.有人可以解释一下最好的素数是什么以及为什么?

.net c# hash primes gethashcode

7
推荐指数
1
解决办法
2423
查看次数

如何使用超过 8 个值的 System.HashCode.Combine?

.NET Standard 2.1 / .NET Core 3引入 System.HashCode了快速将字段和值组合为哈希码的功能,而无需关心底层实现。

但是,它仅提供Combine最多 8 个值的方法重载。如果我有一个包含 9 个值(3x3 矩阵)甚至 16 个值(4x4 矩阵)的类,我该怎么办?

我应该简单地将两个Combine调用相加,并在每个调用中传递尽可能多的值吗?

public override int GetHashCode()
    => HashCode.Combine(M11, M12, M13, M21, M22, M23, M31, M32) + HashCode.Combine(M33);
Run Code Online (Sandbox Code Playgroud)

看看来源,我不能完全争论这是否可能有我不知道的影响。

c# hashcode gethashcode

7
推荐指数
1
解决办法
2206
查看次数

具有列表对象的类的GetHashCode

我有这样一堂课:

public class Cycle
{
          public List<int> Edges
        {
            get;
            private set;
        }

        public override bool Equals(object obj)
        {
            Cycle cycle = (Cycle)obj;

            var list1 = cycle.Edges;
            var list2 = Edges;
            var same = list1.Except(list2).Count() == 0 &&
                       list2.Except(list1).Count() == 0;
            return same;

        }

        public override int GetHashCode()
        {
         //   return Edges.GetHashCode();
        }
} 
Run Code Online (Sandbox Code Playgroud)

如您所见,如果两个Edge列表相同,那么我认为Cycles它们是相同的.

现在的问题是如何实施GetHashCode()

我尝试过Edges.GetHashCode(),但问题是,两个List<Cycle>具有相同Cycle对象但订单不同的将被视为不同,即使它们应该是相同的.

c# gethashcode

6
推荐指数
1
解决办法
4728
查看次数

Hibernate n:m extractHashCode抛出NullPointerException

插入带有hibernate的对象时出现以下异常.从数据库中读取就像一个魅力.我使用MySQL 5.5作为数据库提供程序和hibernate 3.6.5.

我有以下数据库架构:

cell(id,cellid,lac,mcc,mnc,insertTime)
location(id,latitude,longitude,altitude,accuracy,heading,hdop,vdop,pdop,insertTime)
cellatlocation(servingCell,neighbourCell,location,signalStrength,insertTime)
Run Code Online (Sandbox Code Playgroud)

其中单元格和位置中的id是主键和servingCell,neighbourCell和location是cellatlocation中的复合主键.

java.lang.NullPointerException
at org.hibernate.type.descriptor.java.AbstractTypeDescriptor.extractHashCode(AbstractTypeDescriptor.java:88)
at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:196)
at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:191)
at org.hibernate.type.EntityType.getHashCode(EntityType.java:325)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:222)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:126)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:70)
at org.hibernate.engine.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:286)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:211)
at org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:531)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:103)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:345)
at $Proxy17.saveOrUpdate(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

我要插入的类:Cell.java

@Entity
@Table(name = "cell", catalog = "crisis")
public class Cell implements Serializable {

private static final long serialVersionUID = -8532796958180260393L;
@Id
@GeneratedValue(strategy …
Run Code Online (Sandbox Code Playgroud)

mysql hibernate gethashcode composite-primary-key

6
推荐指数
1
解决办法
7081
查看次数

string.GetHashCode()在debug vs release中返回不同的值,我该如何避免这种情况?

令我惊讶的是,下面的方法在debug和release中产生了不同的结果:

int result = "test".GetHashCode();
Run Code Online (Sandbox Code Playgroud)

有什么方法可以避免这种情况吗?

我需要一种可靠的方法来散列字符串,我需要在调试和发布模式下保持一致的值.如果可能的话,我想避免编写自己的哈希函数.

为什么会这样?

仅供参考,反射器给了我:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), SecuritySafeCritical]
public override unsafe int GetHashCode()
{
    fixed (char* str = ((char*) this))
    {
        char* chPtr = str;
        int num = 0x15051505;
        int num2 = num;
        int* numPtr = (int*) chPtr;
        for (int i = this.Length; i > 0; i -= 4)
        {
            num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
            if (i <= 2)
            {
                break;
            }
            num2 = (((num2 << 5) + …
Run Code Online (Sandbox Code Playgroud)

c# string debugging release gethashcode

6
推荐指数
1
解决办法
2675
查看次数

计算具有字符串属性的类的哈希码的最佳方法是什么?

我有一个带有字符串属性的类,我需要重写GetHashCode()方法。

class A
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

第一个想法是做这样的事情:

public override int GetHashCode()
{
    return Prop1.GetHashCode() ^ Prop2.GetHashCode() ^ Prop3.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

第二个想法是:

public override int GetHashCode()
{
    return String.Join(";", new[] {Prop1, Prop2, Prop3}).GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

什么是最好的方法?

c# gethashcode

6
推荐指数
1
解决办法
4775
查看次数

替换System.Drawing.Point的GetHashCode()方法

System.Drawing.PointGetHashCode如果你打算用它来描述图像/位图中的"像素",它有一个非常非常糟糕的方法:它只是X和Y坐标之间的XOR.

因此,对于具有2000x2000大小的图像,它具有荒谬的分数,因为只有对角线中的数字才具有相当好的散列.

GetHashCode正如一些人已经在这里提到的那样,使用未经检查的乘法创建一个合适的方法非常容易.

但是我可以做些什么来使用这种改进的GetHashCode方法HashSet呢?我知道我可以创建自己的类/结构MyPoint并使用这种改进的方法实现它,但是我会破坏我的项目中使用的所有其他代码片段System.Drawing.Point.

是否可以System.Drawing.Point使用某种扩展方法等"覆盖"该方法?或者"告诉" HashSet使用另一个功能而不是GetHashCode

目前我正在使用SortedSet<System.Drawing.Point>带有自定义IComparer<Point>来存储我的积分.当我想知道该集是否包含Point I调用时BinarySearch.它比HashSet<System.Drawing.Point>.Contains具有10000个聚合的集合中的方法更快,但它没有像HashSet好的哈希一样快.

c# performance gdi+ gethashcode

6
推荐指数
1
解决办法
154
查看次数

GetHashCode的好习惯?

对于Delphi项目(使用RAD Studio XE7构建),我想创建一个画笔字典.每个字典项包含一个TMyBrush对象作为键,描述要检索的画笔,以及GDI +画笔作为值.

TMyBrush类包含3个字段

  • 用于确定画笔类型的枚举类型(实体,渐变,......)
  • 描述画笔内容的TBrushInfo类(颜色,换行模式......)
  • 表示钳位字段的TRect

在我的字典中,我想根据他的特征检索画笔,而不是他的实例.例如,我希望通过创建本地TMyBrush实例,将其配置为黑色实体,并使用TryGetValue()函数获取匹配的GDI +值,从我的字典中获取黑色实心画笔.为此,我创建了一个TMyBrushComparer.

编写Equals()函数对我来说不是问题.但是我不知道编写GetHashCode()函数的最佳做法是什么.我倾向于写一个这样的函数:

function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer;
begin
    Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0);
end;
Run Code Online (Sandbox Code Playgroud)

但是我觉得这不是一个很好的做法,这是正确的吗?那么,为我的TMyBrushComparer编写一个好的GetHashCode()函数的最佳实践是什么?

问候

delphi hash tdictionary gethashcode

6
推荐指数
1
解决办法
760
查看次数