[英]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.