代码之家  ›  专栏  ›  技术社区  ›  Rich khmarbaise

Java重写HASCODE()获取StaskOffice流错误

  •  2
  • Rich khmarbaise  · 技术社区  · 16 年前

    所以我对重写hashcode不太熟悉,我似乎对hashcode方法有一些无限递归。

    这里是我的场景,我有一个类DuplicateCache,它是一个缓存对象,用于检查系统中的重复对象。我有一个静态的内部类副本,它表示重复的对象。

    DuplicateCache维护hashmap以跟踪其所有条目。每个条目包含一个作为键的重复对象和一个作为值的长对象。

    我使用复制的对象键执行所有操作,当我将put方法运行到hashmap中时,复制对象的hashcode()方法中会出现无限递归。

    重复的hashcode()方法调用了我必须重写的另一个类的hashcode,因此我将在

    不用再多费吹灰之力,这里是我的代码,用于违规的重复类:

    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;
        }        
    }
    

    这样做是为了复制对象,现在是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,而iso4217代码是一个字符串。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对象

    谢谢!

    3 回复  |  直到 16 年前
        1
  •  5
  •   Michael Borgwardt    16 年前

    用一个 StackOverflowError ,在堆栈跟踪结束的地方(基本上是随机的,可能与问题完全无关),并不重要,但在那之前的重复序列是什么——这应该准确地指出问题所在。

    您的 hashCode() 方法看起来不错,它们不应该导致 栈溢出 .

        2
  •  0
  •   Jherico    16 年前

    发布堆栈跟踪。如果您得到了一个这样的异常,那么显然在对象定义中的某个地方有一个引用循环。堆栈跟踪应使其立即显示在何处。

        3
  •  0
  •   Yuri.Bulkin    16 年前

    在大多数情况下,stackoverflower错误意味着在执行路径中有无休止的递归。