黑马程序员技术交流社区
标题:
关于hashcode和equal
[打印本页]
作者:
逆世界ylm
时间:
2014-12-15 10:37
标题:
关于hashcode和equal
这两者好像都可以来辨别两个对象是否相等,他们的区别和作用是什么,求大神告知
作者:
任我行
时间:
2014-12-15 11:06
1:equals()相等的两个对象,hashcode()一定相等;
2:equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。
换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。
反过来:
3:hashcode()不等,一定能推出equals()也不等;
4:hashcode()相等,equals()可能相等,也可能不等。
作者:
I空空
时间:
2014-12-16 23:05
1:equals()相等的两个对象,hashcode()一定相等;
2:equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。
换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。
反过来:
3:hashcode()不等,一定能推出equals()也不等;
4:hashcode()相等,equals()可能相等,也可能不等。
另外一般复写hashcode()方法时,都需要复写equals方法
作者:
wangcongwu
时间:
2014-12-17 00:28
这样说吧,equals()在集合框架内其实是根据哈希值来判断是否相等的,哈希值是根据你的对象的某些属性来获取的
作者:
wangcongwu
时间:
2014-12-17 00:37
出了集合框架的话equals 就未必是靠哈希值来判断的了,哈希值是地址值和你存储的元素的内容通过某种算法组合出来的一种值,很有可能储存在A内存的数值X 和储存在B内存的数值y 是同一个哈希值,比如你比较一个字符串用equals 比较肯定不一样的X 和 Y 但是也许哈希值一样。
equals 比较的字符串是比较他们的真实值 而不是哈希值。
在哈希集合框架内equals 就靠的是比较哈希值来判断是否是一个元素了。所以为了让你的哈希表也许在同一个哈希值下有两个不同的元素。
需求:去除hashset 中的具有相同值的Person类
package SetShow;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
Iterator it = hs.iterator();
while(it.hasNext())
{
Person p = (Person) it.next();
sop(p.getName()+" : "+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.print(obj);
System.out.println();
}
}
class Person
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public int hashCode()//按照条件而设定哈希值
{
System.out.println(this.name+" hash code "+name.hashCode()+age);
return name.hashCode()+age*27;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))// obj instanceof person:在这里说,obj 是 Person吗
return false;
Person p = (Person) obj;
System.out.println(this.name+"...equals ?..."+p.name);
return this.name.equals(p.name)&& this.age == p.age;
}//this equals 在运行contains 的时候被自动调用了,所以如果想比较其他的元素的内容可以自己编写一遍
}
复制代码
输出结果:
a1 hash code 305611
a2 hash code 305712
a2 hash code 305712
a2...equals ?...a2
a3 hash code 305813
a1 : 11
a2 : 12
a3 : 13
从上边的例子可以看出,equals 方法在使用前是调用的hashcode()方法的,名字和年龄经过哈希算法过后就变成了不同的数值,当第二个a2进入哈希表的时候发现他的哈希值名字和以前的那个a2 一样,所以就调了equals 方法进行比较,比较两个person 的name 和 age,具体的操作是:(第二个a2) .equals(第一个a2)。如果发现哈希值一样,内容也一样就判定指向的是同一个对象,则不会把同一个对象存入哈希表两次。所以后来就自动出现了只存入a1,a2,a3的三个情况。
和list 一样hashset 的remove 和 conatins 方法也是依赖equals方法,equals 依靠的是hashcode。
作者:
wangcongwu
时间:
2014-12-17 00:41
你在集合框架内覆写了equals 方法,这个覆写的方法是依赖哈希值的,而在覆写的equals 方法内,你有调用了一个equals 方法,第二个equals方法是比较的真实值是String 自己的比较方法。
String 自己也是一个类,Sun 公司的程序员保证了这个类的equals 方法肯定能比较出真实值,但是是否使用了哈希值比较就不得而知了目前。
作者:
wangcongwu
时间:
2014-12-17 00:43
如果还不懂我也没招了 去请叫大神们吧
作者:
逆世界ylm
时间:
2014-12-17 08:33
wangcongwu 发表于 2014-12-17 00:43
如果还不懂我也没招了 去请叫大神们吧
懂了,谢谢大神
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2