标签: hashcode

GetHashCode扩展方法

在阅读StackOverflow上有关覆盖的所有问题和答案之后,GetHashCode()我编写了以下扩展方法,以便轻松方便地覆盖GetHashCode():

public static class ObjectExtensions
{
    private const int _seedPrimeNumber = 691;
    private const int _fieldPrimeNumber = 397;
    public static int GetHashCodeFromFields(this object obj, params object[] fields) {
        unchecked { //unchecked to prevent throwing overflow exception
            int hashCode = _seedPrimeNumber;
            for (int i = 0; i < fields.Length; i++)
                if (fields[i] != null)
                    hashCode *= _fieldPrimeNumber + fields[i].GetHashCode();
            return hashCode;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(我基本上只重构了有人在那里发布的代码,因为我真的很喜欢它可以一般使用)

我用的是这样的:

    public override int GetHashCode() {
        return this.GetHashCodeFromFields(field1, field2, field3);
    }
Run Code Online (Sandbox Code Playgroud)

你看到这段代码有什么问题吗?

c# hash hashcode gethashcode

12
推荐指数
1
解决办法
5314
查看次数

字典是否被破坏或GetHashCode()仅基于不可变成员?

将对象添加到.NET System.Collections.Generic.Dictionary类时,密钥的哈希码将在内部存储并用于以后的比较.当哈希码在其初始插入字典后发生变化时,它经常变得"不可访问",并且当存在检查(即使使用相同的引用)返回false时,它可能会使其用户感到惊讶(下面的示例代码).

该GetHashCode的文件说:

为对象GetHashCode方法必须一致,只要没有修改确定的该对象的Equals方法返回值的对象的状态返回相同的散列码.

因此,根据GetHashCode文档,只要更改了相等的确定状态,哈希码就会改变,但Dictionary实现不支持这一点.

当前的.NET字典实现是否被打破,因为它错误地忽略了哈希码限额?应该GetHashCode()只基于不可变成员?或者,还有什么可以打破可能的错误二分法吗?

class Hashable
{
    public int PK { get; set; }

    public override int GetHashCode()
    {
        if (PK != 0) return PK.GetHashCode();
        return base.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Hashable);
    }

    public virtual bool Equals(Hashable other)
    {
        if (other == null) return false;
        else if (ReferenceEquals(this, other)) return true;
        else if (PK != 0 && other.PK != 0) return …
Run Code Online (Sandbox Code Playgroud)

.net c# dictionary hashcode immutability

12
推荐指数
2
解决办法
1782
查看次数

.Net GetHashcode位移操作

我昨天查看了一些.net源代码,看到了GetHashcode的几个实现,其中包含以下内容:

(i1 << 5) + i ^ i2
Run Code Online (Sandbox Code Playgroud)

我理解代码在做什么以及为什么.我想知道的是为什么他们使用(i1 << 5)+ i代替(i1 << 5)- i.

我见过的大多数框架都使用-i,因为它相当于乘以31这是素数,但是微软的方式相当于乘以33,它有11和3作为因子,因此不是素数.

这有什么理由吗?有任何合理的假设吗?

.net hashcode bit-shift

12
推荐指数
1
解决办法
520
查看次数

什么是Java 8中String键的替代散列?

Java 8为String键提供备用散列,以在遇到大量密钥散列码冲突时提高性能.任何人都可以解释它是什么以及它将如何工作?

java collections hash hashmap hashcode

12
推荐指数
2
解决办法
3450
查看次数

在重写hashCode()时使用较大的素数作为乘数

我已经阅读了过去几个小时的哈希码函数,并且在自定义哈希码实现中使用素数作为乘数已经积累了一些问题.如果我能对以下问题有所了解,我将不胜感激:

  • 在对@ mattb的答案的评论中,@ hstoerr主张使用更大的素数(例如524287)而不是公共素数31.我的问题是,给定一对或元素的哈希码函数的以下实现:

    @Override
    public int hashCode() {
        final int prime = 31;
        int hash1 = (pg1 == null) ? 0 : pg1.hashCode();
        int hash2 = (pg2 == null) ? 0 : pg2.hashCode();
        return prime * (hash1 ^ hash2);
    }
    
    Run Code Online (Sandbox Code Playgroud)

这不会导致返回的溢出,int如果prime是大数?

  • 假设溢出是没有问题的(JVM做一个自动施法)是它更好地做一个位位移,而不是一个演员?

  • 我认为哈希码函数的性能根据哈希码的复杂性而有很大差异.主乘数的大小是否不影响性能?

  • 在自定义哈希码函数中使用多个素数而不是单个乘法器更好/更智能/更快?如果没有,还有其他一些优势吗?请参阅@ jinguy对相关问题的回答中的示例:

    public int hashCode() {
        return a * 13 + b.hashCode() * 23 + (c? 31: 7);
    }
    
    Run Code Online (Sandbox Code Playgroud)

其中a是一个int,b是一个 …

java hash primes hashcode

12
推荐指数
1
解决办法
1637
查看次数

Equals和GetHashCode方法不一致

读完这个问题后为什么"int"和"sbyte"GetHashCode函数生成不同的值?我想进一步挖掘并发现以下行为:

sbyte i = 1;            
int j = 1;
object.Equals(i, j) //false (1)
object.Equals(j, i) //false (2) 
i.Equals(j) //false (3)
j.Equals(i) //true (4)
i == j //true (5)
j == i //true (6)
i.GetHashCode() == j.GetHashCode() //false (7)
Run Code Online (Sandbox Code Playgroud)
  1. (3)和(4)之间的差异打破了Equals应该是对称的要求.
  2. (2)和(4)之间的差异与MSDN规范不一致,即:

    如果两个对象不表示相同的对象引用且都不为null,则它调用objA.Equals(objB)并返回结果.这意味着如果objA重写Object.Equals(Object)方法,则调用此覆盖.

  3. (3)和(5)之间的差异意味着operator ==返回true,但是对象在Equals方面不相等.
  4. (4),(5),(6)和(7)之间的差异意味着两个对象在operator ==和Equals方面是相等的,但它们具有不同的哈希码.

我很感兴趣,如果有人能解释为什么我认为在相当基本的.NET类型中观察到不一致的行为.

.net c# equals hashcode

12
推荐指数
1
解决办法
290
查看次数

两个具有相同哈希码但不相等的实例

我正在读一篇名为Java理论和实践的文章中引用的段落:哈希 - 有效且正确地定义hashCode()和equals()

定义相等性 Object类有两种方法可以推断出对象的身份:equals()和hashCode().通常,如果覆盖其中一个方法,则必须覆盖它们,因为它们之间必须保持重要的关系.特别是,如果两个对象根据equals()方法相等,它们必须具有相同的hashCode()值(尽管反之通常不正确).[强调我加入]

我的问题涉及该段的后一部分"虽然反过来通常不正确".如何让一个类的两个不同实例具有相同的hashCode但不相等?

java equals hashcode

12
推荐指数
3
解决办法
1万
查看次数

在Java中允许和接受hashCode和equals方法中的异常吗?

一些类由框架填充(如bean).因此,您无法保证所有字段都已设置.

示例:标记为@Entity通常具有Integer id字段的类.hashCode可以写成:

public int hashCode() {
    return id.hashCode();
}
Run Code Online (Sandbox Code Playgroud)

但是defencive代码可能看起来像:

public int hashCode() {
    return (id != null) ? id.hashCode() : 0;
}
Run Code Online (Sandbox Code Playgroud)

我是否需要使用try { ... } catch (Exception e)in hashCode和equals函数对null或环绕码进行写检查?

我没有关于defencive编码的论据就是这种情况,因为它隐藏了将不一致的对象隐藏到集合中并导致延迟错误.我错了吗?

更新我写了这样的代码:

import java.util.*;

class ExceptionInHashcode {

    String name;

    ExceptionInHashcode() { }
    ExceptionInHashcode(String name) { this.name = name; }

    public int hashCode() {
        // throw new IllegalStateException("xxx");
        return this.name.hashCode();
    }

    public static void main(String args[]) { …
Run Code Online (Sandbox Code Playgroud)

java exception equals hashcode nullpointerexception

12
推荐指数
2
解决办法
4837
查看次数

如何识别已被不恰当地拒绝的Java URI hashCode()错误

Java Object契约的一个基本部分是该hashCode()方法应该与该equals()方法一致.这是有道理的并且易于理解:如果两个对象在某种程度上"相等",则它们应该返回相同的哈希码.如果没有,你可以将一个对象放在一个HashSet,例如,然后检查一个单独的实例是否在集合中并错误地返回false,即使该equals()方法会认为对象是等价的.

事实上,从Java 6开始,Java的URI代码就存在这个问题.试试这段代码:

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.net.URI;

import org.junit.Test;

public class URITest
{

    @Test
    public void testURIHashCode()
    {
        final URI uri1 = URI.create("http://www.example.com/foo%2Abar");
        final URI uri2 = URI.create("http://www.example.com/foo%2abar");
        assertThat("URIs are not equal.", uri1, equalTo(uri2));
        assertThat("Equal URIs do not have same hash code.", uri1.hashCode(), equalTo(uri2.hashCode()));
    }
}
Run Code Online (Sandbox Code Playgroud)

根据RFC 3968,URI转义序列不区分大小写; 也就是说,%2A和%2a被认为是等同的.Java URI.equals()实现将此考虑在内.但是,URI.hashCode()实施并没有考虑到这一点!这意味着,返回两个URI的实例true为URI.equals()但可以返回不同的散列码,如在示出的代码以上!

我提交了这个问题,据说导致了Java …

java uri equals hashcode

12
推荐指数
1
解决办法
635
查看次数

在iOS版本中稳定的String的哈希值?

在String.hashiOS的文档中,它说:

在OS X版本中,不应该依赖具有相同散列值的此属性.

(奇怪的是他们在iOS文档中谈到OS X)

好吧,我需要一个不会因iOS版本而改变的hasshing功能.它可以很简单,我不需要像SHA这样的东西.那有些图书馆吗?

有关于这一个问题在这里,但接受的(唯一的)答案有只是说,我们应该尊重在文档的说明.

hash hashcode nsstring ios swift

12
推荐指数
1
解决办法
3688
查看次数