所以我并不精通覆盖 hashCode 并且我似乎在 hashCode 方法上有一些无限递归。
这是我的场景,我有一个 DuplicateCache 类,它是一个缓存对象,用于检查我们系统中的重复对象。我有一个静态内部类 Duplicate,它代表 Duplicate 对象。
DuplicateCache 维护一个 HashMap 来跟踪它的所有条目。每个条目都包含一个作为键的 Duplicate 对象和一个作为值的 Long 对象。
我正在使用 Duplicate 对象键执行所有操作,当我将 put 方法运行到 HashMap 中时,Duplicate 对象的 hashCode() 方法中会出现无限递归。
重复的 hashCode() 方法调用我必须覆盖的另一个类的 hashCode,所以我将在之后包含它
事不宜迟,这是我的违规 Duplicate 类的代码:
public static class Duplicate{
private String merchId;
private String custId;
private MagicPrice price;
private int status;
private boolean compareStatus;
// snip methods
@Override public boolean equals(Object o){
cat.debug("In the override equals method of Duplicate"); //DELETEME
if(o instanceof Duplicate)
return equals((Duplicate) o);
else
return false;
}
@Override public int hashCode() {
return merchId.hashCode() + custId.hashCode() + price.hashCode();
}
/*Equals method vital to the HashMap cache operations
How the compareStatus and status fields change this:
if both objects have true for compareStatus -> Equals will compare the statuses
otherwise -> Equals will not compare the statuses
If we only want to do an in_progress check, we need to compare status.
On the other hand success checks need to ignore the status.
*/
public boolean equals(Duplicate d){
try{
if(merchId.equals(d.merchId) && custId.equals(d.custId) && (price.compareTo(d.price)==0)){
if(this.compareStatus && d.compareStatus && this.status != d.status)
return false;
return true;
}
}catch(PriceException pe){
//Catching from MagicPrice.compareTo object method, return false
return false;
}
return false;
}
}
这适用于 Duplicate 对象,现在是 MagicPrice hashCode() 方法:
@Override public boolean equals(Object o){
if(!(o instanceof MagicPrice))
return false;
MagicPrice p = (MagicPrice)o;
if(this.iso4217code.equals(p.iso4217code) && this.value.equals(p.value))
return true;
else return false;
}
@Override public int hashCode(){
return value.hashCode() + this.iso4217code.hashCode();
}
在此类中,值字段是 BigDecimal,iso4217code 是字符串。对于它的价值,stackTrace 最终死于 BigDecimal hashCode() 方法,但我不相信 BigDecimal hashCode() 方法会被破坏。
有人可以向我解释一下我对这个 hashCode() 覆盖的遗漏吗?我知道一定有什么我做错了才能产生这种行为。
这是我的日志文件中的堆栈跟踪:
java.lang.StackOverflowError
at java.math.BigDecimal.hashCode(BigDecimal.java:2674)
at com.moremagic.util.MagicPrice.hashCode(Unknown Source)
at com.moremagic.core.DuplicateCache2$Duplicate.hashCode(Unknown Source)
at java.util.HashMap.get(HashMap.java:300)
at com.moremagic.util.ExpirableHashMap.get(Unknown Source)
at com.moremagic.core.DuplicateCache2.put(Unknown Source)
at com.moremagic.core.DuplicateCache2.put(Unknown Source)
at com.moremagic.core.DuplicateCache2.put(Unknown Source)
at com.moremagic.core.DuplicateCache2.put(Unknown Source)
<... and it continues with the put references for a looong time ...>
此外,该跟踪引用了一个专有的 get 方法,因此为您提供:
public Object get(Object key) {
expire();
return hashtable.get(key);
}
expire() 是一种基于时间删除表中旧条目的方法 hashtable 是 HashMap 对象
谢谢!