最近,在网上浏览了关于equals(),hashCode()的文章,强调当一个对象被当作键值(或索引)来使用的时候要重写这两个方法,但我试了一下列子:
  import java.util.HashMap;
  public class Person {
  private String id;
  public String getId(){
    return id;}
    public void setId(String id){
     this.id=id;
     }
     
      public static void main(String args[]){
        Person p=new Person();
       
       Person pp=new Person();
        HashMap map=new HashMap();
        map.put(p,"p1");
        map.put(pp,"p2");
        System.out.print(map.get(p));
        }
        }
  即使没有重写也能得到正确的值p2,为什么

解决方案 »

  1.   

    当你要重写对象的equals方法时,你必须重写该对象的hashcode方法.
    两个对象之间要互相equals的话,就必有具备相同的hashcode.
      

  2.   

    System.out.print(map.get(p)); 
    业务上来讲应该得到p1,你得到p2,还正确??
      

  3.   

    Set的存储机制是equals与hashcode相结合的。一般ADD一个对象会先根据equals方法判断与其他对象是否相等,因为Set是不允许重复add的。如你不覆盖equals方法,JAVA默认所有的对象都是不同的,也就是它们的内存地址。假如你NEW一个对象,人,你认为只要它们名字相同就是同一个对象,此时你就需要覆盖equals方法了,否则同名也是两个对象。java先通过equals方法判断存储位置,如果不同直接存入;如果通过equals方法比较现在要存入的对象与结合中的某个对象相等,那么它就会再根据hashcode来判断它们是否hashcode也相等,如果相等那就存不进去了,说明它们确实是同一个对象,不等就可存入。所以一般在写程序的时候,两个对象你认为它们不同就去覆盖equals方法。这样可以提高效率,不要让JAVA再去判断hashcode
      

  4.   

    package chdw;import java.util.HashMap;public class Person {
    private String id; public String getId() {
    return id;
    } public void setId(String id) {
    this.id = id;
    } public static void main(String args[]) {
    Person p = new Person();
    p.id = "123";
    Person pp = new Person();
    pp.id = "321";
    HashMap map = new HashMap();
    map.put(p, "p1");
    map.put(pp, "p2");


    Person pNew = new Person();
    pNew.id = "123";
    System.out.print(map.get(pNew));
    }
    }最后一句中,本来我应该认为 id 相同,应该可以取出"p1"这个值,但是Map是不知道 pNew 是等同于 p的,所以会返回null
      

  5.   

    没有重写的时候是直接用Object类的equals(),hashCode()的,由于put和get用的是同一个Object--p,
    put和get的时候的hashCode()相等(p.hashCode() == p.hashCode()),
    值相等(p.equals(p)),
    所以能取到.
      

  6.   

    没有重写也可以是因为你还是使用同一个Person对象,当然这个p是与Map中的Key具有相同的hashCode及equals的
    但是像我的代码中,另外创建一个Person对象,虽然我认为应该是相同的Person,但是由于它与Map中的Key具有不相同的HashCode也不equals,所以是取不出来
      

  7.   

    一般你需要比较两个对象是否相等时需重写equals方法,一般在编写领域和实体对象时需重写equeals和hashCode
      

  8.   

    感谢,我想问当一个对象被当作键值(或索引)特别使用在hashmap.hashtable等来使用的时候,什么情况下要重写hashCode(),equals()
      

  9.   

    要重写的  就是 存在以下的情况:
    虽然 a 与 b不是同一个对象(即 a != b),但是你希望无论使用 a 还是 b 都可以从map中取出相同的 value,或者在 set 中不会重复出现也就是你会认为 a 与 b 的内容是相同的
      

  10.   

    除了米怎么其他人说的话都让我摸不着头脑呢?
    equeals和hashCode方法有必然联系吗?
      

  11.   

    在你需要比较对象是否相等的时候 或者使用set的时候
      

  12.   

    但什么时候应该重写呢?
    比如:你向 Set 集合中添加一个一个Person 对象 如果 这个Person 对象的
    name 相同就认为是同一个对象的话。那么你就必须同时重写 hashCode,和equals 方法。
    Set 集合是不可以包含重复元素的 
    Person p1 = new Person("abc");
    Person p2 = new Person("abc");
    p1 ,p2 加到Set 集合中 会是两个对象。
    但事实上是 同一个人。
    这时就必须重写。
      

  13.   

    equeals和hashCode方法有必然联系吗?
    ----
    在Java的规范中规定了有必然的联系, 即 如果 a.equals(b),那么必定有 a.hashCode() == b.hashCode(),反之【不一定成立】如果不满足这个条件则map, set等的处理会出现错误的
    这是一个规范
      

  14.   

    没有重写也得到正确的结果
    是因为对象的继承的Object.hashcode()方法返回的值肯定可以唯一确定这个对象
    重写的原因就是为了改变这个效果(或者其他理由)
      

  15.   

    我只有在做EJB的时候重写过一次equals,当时也是问了别人的!
      

  16.   

    我得到的值为P1。对于hashCode和equals的关系如下:
    如果a==b,则a.equals(b),a.hashCode = b.hashCode.