/*
2008年11月10日11:36:10
连个个问题:
第一: 重写equals()方法为什么还要必须重写hashCode方法?
  如以本程序为例,我在45行已经重写了equals()方法,已经达到了"如果
  两个对象所占内存不同但内存中的值相同就返回true的功能",为什么还要
  重写hashCode方法? 第二:equals()方法会自动调用hashCode方法么?

小弟初学java  请诸位高手指教 先谢谢啦!*/import java.util.*;public class TestBasicContainer
{
public static void main(String[] args)
{
Collection c = new HashSet();
c.add("hello");
c.add(new Integer(100));
c.add(new Name("bin", "hao"));
System.out.println(c); c.remove("hello");
c.remove(100);
c.remove(new Name("bin", "hao"));
System.out.println(c);
}
}class Name
{
private String firstName, lastName; public Name(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
} public String toString()
{
return firstName + "  " + lastName;
} public boolean equals(Object obj)  //45行
{
if (obj instanceof Name)
{
Name name = (Name)obj;
if (this.firstName.equals(name.firstName) && lastName.equals(name.lastName))
{
return true;
}
}
return super.equals(obj);
}// public int hashCode() //48
// {
// System.out.println("哈哈 嘿嘿!");
// return firstName.hashCode();
// }  //52
}
/*
在JDK 1.6中的运行结果是:
--------------------------------
哈哈 嘿嘿!
[hello, 100, bin  hao]
哈哈 嘿嘿!
[]
--------------------------------
从输出结果来看,似乎是equals()方法自动调用了hashCode方法
如果把48到52行注释掉,则在JDK 1.6中的运行结果是:
---------------------------------
[hello, 100, bin  hao]
[bin  hao]
---------------------------------
为什么会这样,为什么必须的重写hashCode()方法????*/

解决方案 »

  1.   

    如果2个对象相等
    那么这2个对象返回的hashcode必须相同
      

  2.   

    给你个网址,上面很详细的,自己看看吧!
    http://topic.csdn.net/t/20060401/22/4656654.html
      

  3.   

    :equals()方法会自动调用hashCode方法么?
    看你如何重写equals方法了,由程序员自己控制!
      

  4.   

    这两个方法必须同时重写 ,是java的常规约定,应该遵守.
    如果写了一个不重写另一个,在把对象放入hashtable ,hashmap等结构中时会出现问题.
    记住 这个约定并遵守就是了. 第二:equals()方法会自动调用hashCode方法么?
    不会.除非你设计一个equals()方法 让它调用hashCode()方法,不过好象没什么意义,也没见过别人这么写.
      

  5.   

    HashSet里的add()方法会通过一系列的调用使用到 hashCode()方法,因为它要根据hash值来确定存储位置,不是equals方法调用的.
      

  6.   

    我个人的理解是这样的 
    当在集合LIST SET 调用方法判断2个对象是否相等的时候底层是看这两个对象是否equals()
    比如
    remove(Object o)这个方法它会去拿着你传入的对象一个一个去equals();当equals成立时就把那个对象给移除了但是别忘了 除了LIST和SET接口外 还有一个集合接口那就是map,实现map接口的集合对象如HashMap,这些对象里存的是键值对,你比较的话这时候底层就会去找hashCode方法而不是equals方法,这是为了程序性能的问题。所以当一个对象你只重写equals方法或hashCode方法,那么势必在一种情况下成立一种情况下不成立,所以只有2个方法同时改的情况下就会在各种情况下都出现你要的结果。我想这就是重写equals()方法必须重写hashCode方法的原因!
    同时我也认为equals()方法不会自动调用hashCode方法!
      

  7.   

    补一句凡是用哈希表实现的集合比较的是hashCode方法 我上面的说法还没考虑到一种情况呵呵
      

  8.   

    hashCode();哈希表用到的,“hash”字母,表示只在哈希表里边用到,zangXT大哥介绍的很清楚,这个东东用来作为哈希表的索引
      

  9.   

    .容器类对象在调用remove,contains等方法时需要比较对象是否相等
    ,这会涉及到对象类型的equals方法和hashCode方法;对于自定义的类型,需要重写equals和hashCode方法以实现自定义对象相等规则
    .注意:相等对象应该具有相等的hash codes
      

  10.   

    public boolean equals(Object obj)      {
            if (obj instanceof Name)
            {
                Name name = (Name)obj;
                if (this.getClass()==name.getClass())
                {
                    return true;
                }else{
                    return false;            
                }   
            }
        }
    你也可以这样啊
      

  11.   

    public boolean equals(Object obj)      {
            if (obj instanceof Name)
            {
                Name name = (Name)obj;
                if (this.getClass()==name.getClass())
                {
                    return true;
                }else{
                    return false;            
                }   
            }
        }
    你也可以这样啊
      

  12.   

    直接抄JDK.hashCode 的常规协定是: 在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。 
    如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。 
    以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。 
    实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。) 
      

  13.   

    这么理解,在你调用equals()方法比较两个对象的时候,编译器会自动调用hashCode()来比较两个对象是否产生相同的整数结果.
    equals()返回true,则hashCode()必返回true.equals()返回false,则hashCode()必返回false.那么你重写equals()方法,肯定必须重写hashCode方法来保证二者的同步关系(暂且称这种关系为同步关系).
      

  14.   

    HashSet中按equals方法判断两个对象是否相等 按 hashCode方法决定存储位置.
    如果不重写hashCode方法就会导致找不对存储位置而认为对象不存在,所以删不掉.
      

  15.   

    老紫竹JAVA提高教程(2)-认识Set集合之HashSet[精]
      

  16.   

    public class Student {
    private String name,sex,grade; public Student(String name, String sex, String grade) {

    this.name = name;
    this.sex = sex;
    this.grade = grade;
    } public String getGrade() {
    return grade;
    } public void setGrade(String grade) {
    this.grade = grade;
    } public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public String getSex() {
    return sex;
    } public void setSex(String sex) {
    this.sex = sex;
    } @Override
    public int hashCode() {
    System.out.println("hashCode");
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + ((grade == null) ? 0 : grade.hashCode());
    result = PRIME * result + ((name == null) ? 0 : name.hashCode());
    result = PRIME * result + ((sex == null) ? 0 : sex.hashCode());
    return result;
    } @Override
    public boolean equals(Object obj) {
    System.out.println("Equals");
    if (this == obj)
    return true;
    if (obj == null)
    return false;
    if (getClass() != obj.getClass())
    return false;
    final Student other = (Student) obj;
    if (grade == null) {
    if (other.grade != null)
    return false;
    } else if (!grade.equals(other.grade))
    return false;
    if (name == null) {
    if (other.name != null)
    return false;
    } else if (!name.equals(other.name))
    return false;
    if (sex == null) {
    if (other.sex != null)
    return false;
    } else if (!sex.equals(other.sex))
    return false;
    return true;
    }
    public static void main(String[] args) {
    Student st1=new Student("java","sun","1993");
    Student st2=new Student(".net","microsoft","2002");
    Student st3=new Student("java","sun","1993");
    if(st1.hashCode()==st3.hashCode()){

    System.out.println(true);
    }
    String a="aa";
    String b="aa";
    System.out.println(a.hashCode()==b.hashCode());
    //结果如下 equals根本不会调用hashCode方法
    /**
     * hashCode
    hashCode
    true
    true
     */
    //顺便算了这二个对象


    }
    }
      

  17.   

      补充一下,刚来写错了一句代码 if(st1.equals(st3)){

    System.out.println(true);
    }
      

  18.   

    根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
      

  19.   

    对Set和Map而言,相同元素是针对同一个类的对象,hashCode和equals方法返回值也相同
    对List而言,相同元素是针对同一个类的对象,equals方法返回值也相同你去查看一下源代码就彻底明白了。《巨和_连金亮_JAVA视频(J2SE),从入门到精通【压缩高清独立光纤下载完整版】》的提供了光线下载,有需求的朋友可以去 http://www.verycd.com/topics/2839540/ 下载。