我无法解释的问题,请您一并来解释

情景上这样的:我有一个重写了equals方法的类,该类源码如下。然后用一程序将此类多次循环put到HashMap中去,但每次put到1500次左右时,就会出现NullPointerException。

  在map.put的方法中,会先去判断put进去的对象是否已经存在于map中,判断方法调用的就是该对象的重写的equals方法,如果说我写的equals有问题的话,为什么前1000多次左右不会出现问题而在最后出现问题呢?起初以为是放到HashMap中的对象太大会出现内存溢出,但并未出现outofmemory异常,用JProfiler进行监测时也发现和heap的使用也没关系……有哪位兄弟帮我解释一下……



  重写了equals方法的类:

public class myPolSchema {

    // @Field

    private String GrpContNo;

    private String GrpPolNo;



    public String getGrpContNo() {

        return GrpContNo;

    }



    public void setGrpContNo(String aGrpContNo) {

        GrpContNo = aGrpContNo;

    }



    public String getGrpPolNo() {

        return GrpPolNo;

    }



    public void setGrpPolNo(String aGrpPolNo) {

        GrpPolNo = aGrpPolNo;

    }



    public boolean equals(Object otherObject) {

        if (this == otherObject)

            return true;

        if (otherObject == null)

            return false;

        if (getClass() != otherObject.getClass())

            return false;

        myPolSchema other = (myPolSchema) otherObject;

        return GrpContNo.equals(other.getGrpContNo())

                && GrpPolNo.equals(other.getGrpPolNo());

    }

}

测试类:



import java.util.* ;

public class MultiThreading{

// implements Runnable

    Map m=Collections.synchronizedMap(new HashMap());

    //HashMap m=new HashMap();

    Hashtable t=new Hashtable();

    public myPolSchema polschema;

    public void run()

    {

        polschema=new myPolSchema();

        m.put(polschema, "UPDATE");

        System.out.println("put end at " + new Date());

    }

    public static void main(String[] args) throws Exception {

        MultiThreading t=new MultiThreading();

        for(int i=0;i <=25000;i++){

            try{

                t.run();

                //Thread.sleep(100);

            }

            catch(Exception ex){

                //在我本地测试时当运行大概1500左右次的时间就会抛出NullPointerException

                System.out.println("i is: " + i);

                throw ex;

            }

        }

    }



}



如果您从源码上看不出来我所说的问题,在此处下载源码……



重写equals的同时需要重写hashCode方法

可以参考:
http://zhangjunhd.blog.51cto.com/113473/71571

建议看《Effective Java》其中关于重写equals和hashCode的内容。

希望以上回复对你有帮助。

重写hashCode()方法。

equals方法可能没有错,但是可能默认的hashcode方法出问题了

effective java上面写道"重写equals方法,也要重写hashcode方法"

在一般情况下,可能你不重写hashcode也没问题,但是当你这种情况时,你使用了map容器,可能两个对象equals==true 但是两个对像的hashcode却不同,就可能发生你这种情况

我修改了一下的代码后,发现没有问题了。
polschema = new myPolSchema();
polschema.setGrpContNo("1");
polschema.setGrpPolNo("2");
m.put(polschema, "UPDATE");
觉得最初的原因是你用的Map m=Collections.synchronizedMap(new HashMap());
除的问题,haspMap是允许为空的,但是里面的属性为空时你不能用来判断。
GrpContNo.equals(other.getGrpContNo())
&& GrpPolNo.equals(other.getGrpPolNo()); 中GrpContNo是空的,至于你前面为什么可以插入一下,不是很理解。
怀疑是[quote]Map m=Collections.synchronizedMap(new HashMap()); [/quote]原因
因为我用hashtable时一个都插不进去

改为:
[code="java"]import java.util.* ;
public class MultiThreading{
// implements Runnable
Map m=Collections.synchronizedMap(new HashMap());
//HashMap m=new HashMap();
Hashtable t=new Hashtable();
public myPolSchema polschema;
public void run(int i)
{
polschema=new myPolSchema();
polschema.setGrpContNo(Integer.toString(i));
polschema.setGrpPolNo(Integer.toString(i));
m.put(polschema, "UPDATE");
System.out.println("put end at " + new Date());
}
public static void main(String[] args) throws Exception {
MultiThreading t=new MultiThreading();
for(int i=0;i <=25000;i++){
try{
t.run(i);
//Thread.sleep(100);
}
catch(Exception ex){
//在我本地测试时当运行大概1500左右次的时间就会抛出NullPointerException
System.out.println("i is: " + i);
throw ex;
}
}
}

}
[/code]
即可,这样hashCode都不会重复,不会再抛异常了(因为你插入的对象的属性都为空串,hashCode很容易重)。