Java Hashcode和excluding字段

Java Hashcode和excluding字段,java,hash,hashcode,Java,Hash,Hashcode,根据Bloch对hashCode的建议: 您可以忽略任何可以从字段计算值的字段 包括在计算中 我不明白。有人能举一个真实的例子吗?我假设,任何可以从其他字段生成字段的类,出于性能原因,只会将其存储在另一个变量中。但是这和hashcode合同有什么关系呢 class Example { final int a; final int b; final int c; Example(int a, int b) { this.a = a; this.b = b; this.c = a

根据Bloch对hashCode的建议:

您可以忽略任何可以从字段计算值的字段 包括在计算中

我不明白。有人能举一个真实的例子吗?我假设,任何可以从其他字段生成字段的类,出于性能原因,只会将其存储在另一个变量中。但是这和hashcode合同有什么关系呢

class Example {
  final int a;
  final int b;
  final int c;

  Example(int a, int b) { this.a = a; this.b = b; this.c = a + b; }
}
在这里的
hashCode
计算中包含
c
是没有意义的:任何
a
b
相等的实例也会有
c
s相等

Objects.hash(this.a, this.b, this.c) == Objects.hash(that.a, that.b, that.c)
  <=>
Objects.hash(this.a, this.b) == Objects.hash(that.a, that.b)

也许很明显,这不能包含在哈希代码计算中!但是它可以从类中的其他字段派生。

考虑一个有更多字段的类

class MyClass {
   String name;
   String surname;
   String fullName;
}
在这个类中,对于hashcode的生成,add唯一有意义的字段是
name
姓氏
。其他字段生成的剩余字段
fullName
可以忽略

但是这和hashcode合同有什么关系呢

class Example {
  final int a;
  final int b;
  final int c;

  Example(int a, int b) { this.a = a; this.b = b; this.c = a + b; }
}
它不构成
hashcode()
契约的一部分。你应该认为把它作为一种有效的方式来实现它是一个很好的实践(因为它可以避免一些无助的计算)。 实际上,
hashCode()
的良好实现应该依赖于与
equals()
方法使用的字段相同的字段。
如果您有一个包含3个字段的类,例如
Addition

class Addition {
  private float operandOne;
  private float operandTwo;
  private float result;
}
您不需要在
equals()
方法中使用
result
,因为
result
在某种程度上是一个冗余信息,您不需要它以独特的方式标识一个
添加
实例。
如果代码< >操作数< /COD>和<代码>操作2和代码>从一个代码>添加< /代码>实例与<代码>操作数< /代码>和<代码>操作>两个/代码>从另一个代码>添加< /代码>实例中,就足够考虑它们了。


hashcode()
方法中,它是相同的。

我怀疑,但这怎么可能是真正的代码呢?实际上,你为什么要保留一个字段
c
?@Jim要么是为了性能,要么是为了便于记谱(即避免在任何地方都写
a+b
getC()
)。实际上,为什么
result
会成为
Addition
的成员字段,不常见,我同意你的观点,但这只是一个例子,展示了一个简单的派生值。您可以将
加法
替换为
bigcumpulations
,它包含最终结果,但也包含由此结果派生的结果。