[英]Is the below is correct equals and hashCode implementation in Java?
当一个对象的值相等时,我需要返回它为true。
例
@Override
public int hashCode() {
return new HashCodeBuilder().append(value).toHashCode();
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof NumberValTO) {
final NumberValTO other = (NumberVal) obj;
return new EqualsBuilder().append(value, other.getValue()).isEquals();
}
return false;
}
以上是好的还是错误的?
在少数应用程序中,我看到哈希码在表的每个字段中都为多个,并且不确定是否正确。
假设一个实体有4列假设一个实体有2列
谢谢。
您的示例很好,因为它提供了equals和hashcode方法的公平实现。 我在项目中使用这种方式。
为您解答1个问题您可以阅读http://www.ideyatech.com/2011/04/effective-java-equals-and-hashcode/
要回答2个问题,请点击以下链接: 休眠:什么时候需要实现equals()和hashCode(),如果需要,如何实现?
是的,这很好,假设这些是您正在使用的Apache Commons帮助器类。 @Vino是正确的,指出添加if (obj == this) return true;
在equals
方法的开始可能是一个值得优化的方法,但是您的方法看起来仍然正确。
您的equals
和hashCode
方法都正确地使用了Apache commons-lang的EqualsBuilder和HashCodeBuilder ,尽管您应该向equals
方法添加引用检查- if (obj == this) return true
equals
。
我最近被反对使用EqualsBuilder和HashCodeBuilder的一个论据是它的性能较差,因此我对其进行了测试。
我创建了一个HashMap
,添加了1万个条目,然后比较了相同键对象的查找时间,一次使用了传统的equals
和hashCode
,然后再次使用了EqualsBuilder和HashCodeBuilder 。 想法是,通过键获取值将锤击equals
和hashCode
方法,并对其性能进行良好的比较。
尽管EqualsBuilder和HashCodeBuilder实现的速度较慢,但差异在60ns左右, commons-lang实现的平均查找时间约为320ns,传统方法的平均查找时间为260ns(我在下面展示了我使用的代码) 。
恕我直言,只有在大量对象上反复调用equals
和hashCode
情况下,才应该考虑这种性能损失,即使在这种情况下,只有很小的性能提升就值得牺牲代码的清晰度。
无论如何,这是我用来测试性能差异的类:
public class Example
{
private Type operationType;
private long identity;
private String name;
private BigDecimal value;
public Example(Type operationType, long identity, String name, BigDecimal value)
{
this.operationType = operationType;
this.identity = identity;
this.name = name;
this.value = value;
}
public Example(Example example)
{
this.operationType = example.operationType;
this.identity = example.identity;
this.name = example.name;
this.value = example.value;
}
public long getIdentity()
{
return identity;
}
public String getName()
{
return name;
}
public BigDecimal getValue()
{
return value;
}
@Override
public boolean equals(Object obj)
{
if (Type.TRADITIONAL.equals(operationType))
{
if (this == obj)
{
return true;
}
if (obj == null || getClass() != obj.getClass())
{
return false;
}
Example example = (Example)obj;
return getIdentity() == example.getIdentity()
&& ((getName() == null && example.getName() == null) || getName().equals(example.getName ()))
&& ((getValue() == null && example.getValue() == null) || getValue().equals(example.getValue()));
}
else
{
return this == obj || obj instanceof Example &&
new EqualsBuilder()
.append(getIdentity(), ((Example)obj).getIdentity())
.append(getName(), ((Example)obj).getName())
.append(getValue(), ((Example)obj).getValue())
.isEquals();
}
}
@Override
public int hashCode()
{
if (Type.TRADITIONAL.equals(operationType))
{
int result = (int)(getIdentity() ^ (getIdentity() >>> 32));
result = 31 * result + (getName() != null ? getName().hashCode() : 0);
result = 31 * result + (getValue() != null ? getValue().hashCode() : 0);
return result;
}
else
{
return new HashCodeBuilder().append(getIdentity()).append(getName()).append(getValue()).toHashCode();
}
}
public static enum Type
{
TRADITIONAL,
COMMONS
}
}
这是测试:
public class ExampleTest
{
@Test
public void testMapLookupWithTraditional() throws Exception
{
double total = 0;
for (int i = 0; i < 10; i++)
{
total += testMapLookup(Example.Type.TRADITIONAL);
}
System.out.println("Overall Average: " + (total / 10));
}
@Test
public void testMapLookupWithCommons() throws Exception
{
double total = 0;
for (int i = 0; i < 10; i++)
{
total += testMapLookup(Example.Type.COMMONS);
}
System.out.println("Overall Average: " + (total / 10));
}
private double testMapLookup(Example.Type operationType) throws Exception
{
Map<Example, String> examples = new HashMap<Example, String>();
while (examples.size() < 10000)
{
long now = System.currentTimeMillis();
Example example = new Example(
operationType,
now,
"EXAMPLE_" + now,
new BigDecimal(now)
);
examples.put(example, example.getName());
Thread.sleep(1);
}
int count = 0;
double average = 0;
double max = 0;
double min = Double.MAX_VALUE;
for (Example example : examples.keySet())
{
Example copiedExample = new Example(example);
long start = System.nanoTime();
examples.get(copiedExample);
long duration = System.nanoTime() - start;
average = ((average * count++) + duration) / count;
if (max < duration) max = duration;
if (min > duration) min = duration;
}
System.out.println("Average: " + average);
System.out.println("Max: " + max);
System.out.println("Min: " + min);
return average;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.