/*
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()方法????*/
那么这2个对象返回的hashcode必须相同
http://topic.csdn.net/t/20060401/22/4656654.html
看你如何重写equals方法了,由程序员自己控制!
如果写了一个不重写另一个,在把对象放入hashtable ,hashmap等结构中时会出现问题.
记住 这个约定并遵守就是了. 第二:equals()方法会自动调用hashCode方法么?
不会.除非你设计一个equals()方法 让它调用hashCode()方法,不过好象没什么意义,也没见过别人这么写.
当在集合LIST SET 调用方法判断2个对象是否相等的时候底层是看这两个对象是否equals()
比如
remove(Object o)这个方法它会去拿着你传入的对象一个一个去equals();当equals成立时就把那个对象给移除了但是别忘了 除了LIST和SET接口外 还有一个集合接口那就是map,实现map接口的集合对象如HashMap,这些对象里存的是键值对,你比较的话这时候底层就会去找hashCode方法而不是equals方法,这是为了程序性能的问题。所以当一个对象你只重写equals方法或hashCode方法,那么势必在一种情况下成立一种情况下不成立,所以只有2个方法同时改的情况下就会在各种情况下都出现你要的结果。我想这就是重写equals()方法必须重写hashCode方法的原因!
同时我也认为equals()方法不会自动调用hashCode方法!
,这会涉及到对象类型的equals方法和hashCode方法;对于自定义的类型,需要重写equals和hashCode方法以实现自定义对象相等规则
.注意:相等对象应该具有相等的hash codes
if (obj instanceof Name)
{
Name name = (Name)obj;
if (this.getClass()==name.getClass())
{
return true;
}else{
return false;
}
}
}
你也可以这样啊
if (obj instanceof Name)
{
Name name = (Name)obj;
if (this.getClass()==name.getClass())
{
return true;
}else{
return false;
}
}
}
你也可以这样啊
如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
equals()返回true,则hashCode()必返回true.equals()返回false,则hashCode()必返回false.那么你重写equals()方法,肯定必须重写hashCode方法来保证二者的同步关系(暂且称这种关系为同步关系).
如果不重写hashCode方法就会导致找不对存储位置而认为对象不存在,所以删不掉.
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
*/
//顺便算了这二个对象
}
}
System.out.println(true);
}
对List而言,相同元素是针对同一个类的对象,equals方法返回值也相同你去查看一下源代码就彻底明白了。《巨和_连金亮_JAVA视频(J2SE),从入门到精通【压缩高清独立光纤下载完整版】》的提供了光线下载,有需求的朋友可以去 http://www.verycd.com/topics/2839540/ 下载。