簡體   English   中英

我可以在沒有 Equals 的情況下使用 GetHashCode 嗎?

[英]Can I use GetHashCode without Equals?

也許我不明白什么。 不,我絕對不明白什么。 有一個帶有兩個 int 類型屬性的自定義類。 重寫 GetHashCode 方法,我想使用這兩個屬性作為獲取哈希碼的基礎。 但是,由於GetHashCode方法的返回類型是int,而我的類中的兩個屬性都是int。 事實證明,我的屬性的各種值的組合會比int類型可以容納的多。 結果,無論如何,我都會發生碰撞。 對? 此外,我想說我嘗試了幾種標記為可接受答案的算法,來自其他主題,其中包括 Jon Skeet 等權威人士提供了他們的選擇,但仍然發生沖突。

    public class Equivalent
    {
        public Equivalent(int a, int b)
        {
            A = a;
            B = b;
        }

        public int A { get; }
        public int B { get; }

        public override int GetHashCode()
        {
            var vals = new[]
            {
                A.GetHashCode(),
                B.GetHashCode()
            };

            var hash1 = (5381 << 16) + 5381;
            var hash2 = hash1;

            var i = 0;
            foreach (var hashCode in vals)
            {
                if (i % 2 == 0)
                    hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ hashCode;
                else
                    hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ hashCode;

                ++i;
            }

            return hash1 + (hash2 * 1566083941);
        }

        public override string ToString()
        {
            return $"{A};{B}";
        }
    }

    public void GetHash()
    {
        var len = 1000000;
        var d = new Dictionary<int, Equivalent>();
        for (var i = 0; i < len; i++)
        {
            var eq = new Equivalent(
                _r.Next(int.MinValue, int.MaxValue),
                _r.Next(int.MinValue, int.MaxValue));

            var hash = eq.GetHashCode();
            if (d.TryGetValue(hash, out var saved))
            {
                File.AppendAllText("result2.csv", $"{hash};{saved}\n");
                File.AppendAllText("result2.csv", $"{hash};{eq}\n");
                continue;
            }

            d.Add(hash, eq);
            Thread.Sleep(1);
        }
    }

我懷疑您正試圖將GetHashCode用於它不適合的用途。 查看此 SO 答案以了解更多上下文。

我不完全確定我理解if (d.TryGetValue(hash, out var saved))背后的意圖 - 我假設您想檢查您是否已經將此特定行保存到您的 CSV 中。 如果確實如此,您可能會發現維護 HashSet 更容易,因為它基本上屏蔽了您的int鍵,同時允許您檢查唯一性:

    for (var i = 0; i < len; i++)
    {
        var eq = new Equivalent(
            _r.Next(int.MinValue, int.MaxValue),
            _r.Next(int.MinValue, int.MaxValue));

        if(!d.Contains(eq))
        {
            //File.AppendAllText("result2.csv", $"{hash};{saved}\n"); // do you need this line?
            File.AppendAllText("result2.csv", $"{eq.GetProperSha1Hash()};{eq}\n");//you will need to implement the method, but there's plenty examples
            d.Add(eq);
            continue;
        }
        Thread.Sleep(1);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM