黑马程序员技术交流社区

标题: HashSet自定义对象练习(上) [打印本页]

作者: itheima_llt    时间: 2015-4-14 23:49
标题: HashSet自定义对象练习(上)
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。

思路:
1 把数据存入Person,建立Person类
2 把Person对象存入HashSet,建立HashSet集
先运行一遍,观察运行结果,进行分析。
  1. import java.util.*;
  2. //1 把数据存入Person,建立Person类
  3. class Person
  4. {
  5.         private String name;//姓名
  6.         private int age;//年龄

  7.         Person(String name,int age)
  8.         {
  9.                 this.name = name;
  10.                 this.age = age;
  11.         }

  12.         public void setName(String name)
  13.         {
  14.                 this.name = name;
  15.         }

  16.         public String getName()
  17.         {
  18.                 return name;
  19.         }

  20.         public void setAge(int age)
  21.         {
  22.                 this.age =age;
  23.         }

  24.         public int getAge()
  25.         {
  26.                 return age;
  27.         }
  28. }

  29. //主类
  30. class HashSetTest
  31. {
  32.         public static void main(String[] args)
  33.         {
  34.                 //1 创建HashSet集
  35.                 HashSet hs = new HashSet();

  36.                 //2 把Person对象存入集合
  37.                 hs.add(new Person("Jack",20));
  38.                 hs.add(new Person("Jack",20));
  39.                 hs.add(new Person("Tom",18));
  40.                 hs.add(new Person("Tom",18));
  41.                 hs.add(new Person("Mike",19));
  42.                 hs.add(new Person("Jane",26));

  43.                 //3 取出元素
  44.                 for(Iterator it = hs.iterator(); it.hasNext(); )
  45.                 {
  46.                         //强制转换为Person
  47.                         Person p = (Person)it.next();
  48.                         System.out.println(p.getName()+"---"+p.getAge());
  49.                 }
  50.         }
  51. }
复制代码

运行结果为:


Tom---18
Jack---20
Jane---26
Jack---20
Tom---18
Mike---19
观察发现,元素并没有去重,这是为什么呢??
这是因为HashSet调用了Object中的hashCode方法!
程序是这样工作的:
JVM调用hashCode方法计算了元素的地址值,
如果地址值不冲突,则存入HashSet。
而上面调用add方法时,每一个Person对象都是在内存新开辟一块空间,
地址值都是不一样的,不可能发生地址冲突,所以都成功的存入了HashSet。

所以,首先必须要做的事就是在Person类中覆盖Object的hashCode方法!
那么到底该怎么重写呢?
这里提供两种方式:
方式一:
public int hashCode()
{
        return 60;
}
方式二:
public int hashCode()
{
        return name.hashCode()+age*37;
}
需要解释的地方:
使用方式一,程序是这样走的:
每一个对象返回的哈希值都一样,发生了冲突,
那么它们就以链表的方式链接存储,
这样存入的元素越多,效率就越低,
为了减少比较次数,
就设计到了hashCode()的算法优化能力!
这里采用了简单的处理,如方式二。

使用方式二:
name是String类型的,String类已经覆盖了hashCode()方法,
所以,可以通过调用得到name的哈希值。
而age*37是为了减少哈希值相等的几率,
减少计算量,提高效率!
同时应该考虑到int的取值范围,应当用“+”求和,
而不是直接把name的哈希值乘以age。



作者: itheima_llt    时间: 2015-4-15 10:56
版主给点分啊!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2