黑马程序员技术交流社区
标题:
hashset中的问题
[打印本页]
作者:
朱弋
时间:
2012-8-10 12:21
标题:
hashset中的问题
毕老师视频中说到在hashset集合中存入元素时,会先比较元素的哈希值,若相同再equals比较。
请教下各位:但这里比较完后,为什么每个元素还会调用一次hashcode()方法
预期运行结果:
wang01hashcode
wang02hashcode
wang03hashcode
wang03hashcode
wang03..equals..wang03
[Person@d09b2415,
Person@d09b2429
,
Person@d09b243d
]
实际运行结果:(附件有图)
wang01hashcode
wang02hashcode
wang03hashcode
wang03hashcode
wang03..equals..wang03
wang01hashcode
wang02hashcode
wang03hashcode
[Person@d09b2415,
Person@d09b2429
,
Person@d09b243d
]
import java.util.*;
class HashSetDemo
{
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("wang01",11));
hs.add(new Person("wang02",12));
hs.add(new Person("wang03",13));
hs.add(new Person("wang03",13));
print(hs);
}
public static void print(Object obj)
{
System.out.println(obj);
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public boolean equals(Object obj) //复写equals方法,判断姓名和年龄是否相同。
{
if (!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.getName()+"..equals.."+p.getName()); //调用equals方法时,打印调用对象的姓名和比较对象的姓名。
return this.getName().equals(p.getName()) && this.getAge() == p.getAge(); //判断姓名和年龄是否相同,并返回判断结果。
}
public int hashCode() //复写Object类中的hashCode方法,获取仅与姓名和年龄有关的哈希值。
{
//调用hashCode时,打印出调用对象的姓名+hashcode。
System.out.println(getName()+"hashcode");
return name.hashCode()+age*19;
}
}
复制代码
1.jpg
(40.7 KB, 下载次数: 22)
下载附件
2012-8-10 12:15 上传
作者:
朱志辉
时间:
2012-8-10 13:15
因为你没在Person类中重写toString方法,所以在输出时调用的是Object的toString方法,该方法的返回值是getClass().getName() + '@' + Integer.toHexString(hashCode()),所以还会调用一次hashcode方法
作者:
王程
时间:
2012-8-10 13:19
wang01hashcode
wang02hashcode
wang03hashcode
wang03hashcode
wang03..equals..wang03
wang01hashcode
wang02hashcode
wang03hashcode
import java.util.*;
class HashSetDemo
{
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("wang01",11));
hs.add(new Person("wang02",12));
hs.add(new Person("wang03",13));
hs.add(new Person("wang03",13));
print(hs);
}
public static void print(Object obj)
{
System.out.println(obj);
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public boolean equals(Object obj) //复写equals方法,判断姓名和年龄是否相同。
{
if (!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.getName()+"..equals.."+p.getName()); //调用equals方法时,打印调用对象的姓名和比较对象的姓名。
return this.getName().equals(p.getName()) && this.getAge() == p.getAge(); //判断姓名和年龄是否相同,并返回判断结果。
}
public int hashCode() //复写Object类中的hashCode方法,获取仅与姓名和年龄有关的哈希值。
{
//调用hashCode时,打印出调用对象的姓名+hashcode。
System.out.println(getName()+"hashcode");
return name.hashCode()+age*19;
}
}
复制代码
hs.add(new Person("wang01",11));
hs.add(new Person("wang02",12));
hs.add(new Person("wang03",13));往Hashset集合中存储对象时,程序会先调用hashcode方法,给每一个传入的对象设置一个哈希值,这一步中你的hashcode方法中有了System.out.println(getName()+"hashcode"); 语句,所以有了一开始的三句打印语句,当hashset集合中存入相同的元素时hs.add(new Person("wang03",13));也是先调用hashcode方法,所以依然有了wang03hashcode的打印语句,发现哈希值相同后,程序执行equals方法,这时就有了System.out.println(this.getName()+"..equals.."+p.getName()); //调用equals方法时,打印调用对象的姓名和比较对象的姓名。所以wang03..equals..wang03的语句,最后的print(hs); 语句因为并没有覆盖toString()方法,所以执行的还是Object类中的toString方法,
方法的源代码如下:
getClass().getName() + '@' + Integer.toHexString(hashCode())
现在楼主明白了吧
作者:
朱弋
时间:
2012-8-10 13:40
明白了。谢谢两位。问题已解决。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2