alex safsafsd Asked:2020-06-14 07:37:57 +0000 UTC2020-06-14 07:37:57 +0000 UTC 2020-06-14 07:37:57 +0000 UTC Hashcode java及其形成 772 你能告诉我如果对象的字段发生变化,对象的哈希码是否应该改变? java 5 个回答 Voted Best Answer Barmaley 2020-06-14T15:23:19Z2020-06-14T15:23:19Z 没必要,看这里: public class HelloWorld { public static void main(String[] args) { //создаем объект MyMutable myMutable = new MyMutable(1, "Hello"); System.out.println("intValue="+myMutable.getIntValue()+", stringValue="+myMutable.getStringValue()+", hashcode="+myMutable.hashCode()); //мутируем (меняем) его свойства myMutable.setIntValue(2); myMutable.setStringValue("World!"); //проверяем hashCode() System.out.println("intValue="+myMutable.getIntValue()+", stringValue="+myMutable.getStringValue()+", hashcode="+myMutable.hashCode()); } } class MyMutable { private int intValue; private String stringValue; public MyMutable(int intValue, String stringValue) { this.intValue=intValue; this.stringValue=stringValue; } public void setIntValue(int intValue) { this.intValue=intValue; } public int getIntValue() { return this.intValue; } public void setStringValue(String stringValue) { this.stringValue=stringValue; } public String getStringValue() { return this.stringValue; } } 结论: intValue=1,stringValue=你好,hashcode=1829164700 intValue=2, stringValue=World!, hashcode=1829164700 我特地介绍了2个不同的字段,反正变化的时候hashCode()不重新计算,保持不变。 更新 在评论中的讨论之后: 1)在默认实现hashCode()中,对象发生变异时不会改变 2)为了改变它,有必要重新定义它hashCode(),例如,对于给出的示例,如下所示: public int hashCode() { return super.hashCode()+ this.intValue+ ((this.stringValue==null?0:this.stringValue.hashCode()); } Bakhuss 2020-06-14T08:21:00Z2020-06-14T08:21:00Z https://habr.com/post/168195/ 相同对象是具有相同字段内容的同一类的对象。 如果对象相同,则哈希码相同(但反之则不然,参见规则 3)。 Hivemaster 2020-06-14T11:29:59Z2020-06-14T11:29:59Z 是的,它应该。这是他们在文档中所说的: hashCode 的一般合约是: 每当在 Java 应用程序执行期间对同一个对象多次调用它时,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。 如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要对两个对象中的每一个调用 hashCode 方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。 这来自第二段和第一段的突出部分。但请记住,该方法的默认实现hashCode不遵循这些原则,因此必须始终覆盖它。 Alex 2020-06-19T19:34:04Z2020-06-19T19:34:04Z 很简单: 如果你在描述你的对象时没有重写 hashcode 方法,那么当它被初始化(调用new)时,它会被默认分配一个标识散列 - 散列。这是使用标准本机方法完成的。 在这种情况下,您对象的字段不会以任何方式影响哈希码的形成,因此对这些字段的任何更改都不会导致哈希码的更改。应该记住,创建一个新的相似对象并不能保证哈希码匹配 。如果您显式覆盖哈希码方法并计算与您的字段值相关的哈希对象,那么当您更改哈希码时也会改变 Rootware 2020-06-14T16:08:25Z2020-06-14T16:08:25Z 使用类似这个模型的东西会更正确,因为您决定使用自己的哈希计算器: public class Test { private int _a; private int _b; private int _c; public Test(int a, int b, int c) { _a = a; _b = b; _c = c; } @Override public int hashCode() { return _a ^ _b ^ _c; } } super.hashcode()并且如果某些条件发生变化,则在通过请求时不需要返回JVM本身生成的对象的哈希码。在我看来,这是不礼貌的行为。
没必要,看这里:
结论:
我特地介绍了2个不同的字段,反正变化的时候
hashCode()不重新计算,保持不变。更新
在评论中的讨论之后:
1)在默认实现
hashCode()中,对象发生变异时不会改变2)为了改变它,有必要重新定义它
hashCode(),例如,对于给出的示例,如下所示:https://habr.com/post/168195/
相同对象是具有相同字段内容的同一类的对象。
如果对象相同,则哈希码相同(但反之则不然,参见规则 3)。
是的,它应该。这是他们在文档中所说的:
这来自第二段和第一段的突出部分。但请记住,该方法的默认实现
hashCode不遵循这些原则,因此必须始终覆盖它。很简单:
如果你在描述你的对象时没有重写 hashcode 方法,那么当它被初始化(调用new)时,它会被默认分配一个标识散列 - 散列。这是使用标准本机方法完成的。
在这种情况下,您对象的字段不会以任何方式影响哈希码的形成,因此对这些字段的任何更改都不会导致哈希码的更改。应该记住,创建一个新的相似对象并不能保证哈希码
匹配 。如果您显式覆盖哈希码方法并计算与您的字段值相关的哈希对象,那么当您更改哈希码时也会改变
使用类似这个模型的东西会更正确,因为您决定使用自己的哈希计算器:
super.hashcode()并且如果某些条件发生变化,则在通过请求时不需要返回JVM本身生成的对象的哈希码。在我看来,这是不礼貌的行为。