黑马程序员技术交流社区
标题:
关于HashSet集合判断元素的问题
[打印本页]
作者:
唐巍
时间:
2012-3-21 02:38
标题:
关于HashSet集合判断元素的问题
HashSet集合在判断集合元素是否存在时,为什么需要通过元素的两个方法hashCode和equals来实现?能不能只用其中一种方法?还有,下面这个hashCode方法:
public int hashCode()
{
return name.hashCode()+age*46;//这里age*46是什么意思?
}
作者:
♂诸侯♂
时间:
2012-3-21 03:08
本帖最后由 ♂诸侯♂ 于 2012-3-21 03:12 编辑
hashSet里边会有一个默认的比较方法,判断hashSet中元素是否相同 通过hashCode 和equals方法来比较
先比较元素hashCode值是不是相同 如果相同 才会判断equals方法是否为true 是的话两元素就相同 不是的话就是不同
是为了保证元素唯一性的。
这个里边 你首先要了解的是 set集合中元素是不可以重复的 如果元素重复了 那么后边的将不会进入集合中 。
这个题中它返回的是name.hashCode()+age*46 简单说就是一个数 如果直接是name.hashCode()+age这个的话 那么很有可能会出现这样一种情况 name.hashCode()是30 age是10 那么他们的和是40 而这时另一个元素中 name.hashCode()是10 age是30 那么另一元素的和也是40 这样hashCode方法就判断两元素相同 回去用equals方法比较 效率较低 所以可以让age*46 这样他们的和算的时候相同的几率就比较小 很少会用到equals方法去比较了 这样效率较高 乘号后边可以是任意的一个数 关键不在这个数是几的问题 而是说乘以一个数 很大可能会让他们通过hashCode方法直接就比较出来是不是相同
package Test;
import java.util.HashSet;
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+"....hashCode");
return name.hashCode()+age*37;
}
public boolean equals(Object obj)
{
if(!(obj instanceof 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;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
复制代码
作者:
刘元明
时间:
2012-3-21 09:03
HashSet是Set集合的子类,而在Set体系中必须保证元素是唯一的,这在HashSet集合中就是通过元素的两个方法hashCode和equals来实现的。
此时判断元素的存在性只是间接的,并不是说元素的这两种方法就是为了判断存在性的
而至于name.hashCode()+age*46中*46只是为了减小由于偶然姓名、年龄的选取导致的该hash值相同出现错误判断的机率
作者:
朱辉
时间:
2012-3-21 11:03
往HashSet集合里面存入元素的时候,默认的会首先调用hashCode()方法,去判断所存元素的hash值和集合里面元素的hash值是否相同,若果不相同就把元素存入到集合中,如果相同了就会调用equals方法再进行比较。打个比方说
Student s1 = new Student("zhangsan",25);
Student s2 = new Student("zhangsan",25);
创建了两个学生对象,我们存入的意思是如果姓名和年龄都相同,就是同一个,第二个不往里面存,如果不覆写hashCode()这个方法这两个学生对象往HashSet集合里面存的话,肯定都会存进去的,因为两个学生对象的地址值都不一样。可以看下面的代码
import java.util.*;
public class HashSetDemo {
public static void main(String[] args){
HashSet hs = new HashSet();
hs.add(new Student("zhangsan",26));
hs.add(new Student("lisi",25));
hs.add(new Student("wangwu",21));
hs.add(new Student("wangwu",21));
hs.add(new Student("zhangsan",26));
Iterator it = hs.iterator();
while(it.hasNext()){
Student s = (Student)it.next();
System.out.println(s.getName()+".."+s.getAge());
}
}
}
class Student{
private String name;
private int age;
Student(String name,int age){
this.name = name;
this.age = age;
}
public int hashCode(){
System.out.println("hashCode"+"..."+this.name);
return name.hashCode()+age*21;
}
public boolean equals(Object obj){
if(!(obj instanceof Student))
return false;
Student s = (Student)obj;
System.out.println(this.name+".."+s.name);
System.out.println(this.age+".."+s.age);
return this.name.equals(s.name)&&this.age==s.age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
复制代码
如果没有覆写hashCode();只覆写equals()方法的话,直接判断完地址值不相同就会把对象都存进去,根本不会再去调用equals()方法。
至于你说的return name.hashCode()+age*46;这里age*46是为了提高效率,使其尽量在hashCode()方法里判断完是否为同一个元素。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2