A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孟浩然 中级黑马   /  2012-6-26 17:08  /  2229 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 孟浩然 于 2012-6-26 21:30 编辑

在毕老师的HashSet视频里面,创建了Person对象,并且把他们添加到hashset集合中去,此时要判断元素是否相同,必须要覆写对象hashcode方法和equals方法;今天了解了一下java对象池的应用,并把这个例子用对象池写了一下,有一点疑问:我用来装对象的对象池也是hashset集合,为什么在添加对象时不用再覆写hashcode方法了,是因为这里不需要用了,还是元素已经调用了而我我不知道,这个到底怎么解释?代码贴出来吧:
  1. import java.util.*;
  2. class HashSetDemo_6
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 HashSet<Person> hs=new HashSet<Person>();
  7.                 Person p1=Person.newPerson("zhangsan01",20);
  8.                 Person p2=Person.newPerson("zhangsan01",20);//不会被添加
  9.                 Person p3=Person.newPerson("zhangsan02",22);
  10.                 Person p4=Person.newPerson("zhangsan03",25);
  11.                 hs.add(p1);
  12.                 hs.add(p2);
  13.                 hs.add(p3);
  14.                 hs.add(p4);
  15.                 Iterator<Person> it=hs.iterator();
  16.                 while (it.hasNext())
  17.                 {
  18.                         Person p=it.next();
  19.                         System.out.println(p.getName()+"::"+p.getAge());
  20.                 }
  21.         }
  22. }

  23. class Person
  24. {
  25.         private String name;
  26.         private int age;
  27.         //创建对象池 用于存储Person对象
  28.         private static HashSet<Person> objectPool=new HashSet<Person>();

  29.         public Person(String name,int age)
  30.         {
  31.                 this.name=name;
  32.                 this.age=age;
  33.         }
  34.         public String getName()
  35.         {
  36.                 return name;
  37.         }
  38.         public int getAge()
  39.         {
  40.                 return age;
  41.         }
  42.         //定义方法,用于创建Person对象
  43.         public static Person newPerson(String name,int age)
  44.         {
  45.                 for (Person p:objectPool )
  46.                 {
  47.                         //如果对象已经在对象池中存在,则直接返回该对象
  48.                         if(p.name.equals(name)&&p.age==age)
  49.                                 return p;
  50.                 }
  51.                 //如果该对象不存在,则创建新对象,并将该对象添加到对象池中
  52.                 Person p=new Person(name,age);
  53.                 objectPool.add(p);
  54.                 return p;
  55.         }
  56. }

复制代码

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

7 个回复

倒序浏览
Person p1=Person.newPerson("zhangsan01",20);在对象池里有这个对象了,第二次Person p2=Person.newPerson("zhangsan01",20);/返回的是你之前添加进去的对象,是同一个对象肯定加不进去,这和重不重写hashcode没关系,
只要你使用了HashSet,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hashcode值是否与增加的对象的hashcode值一致;如果不一致,直接加进去;如果一致,再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则加进去。你的对象池本身就是一个HashSet,里边的元素不可能重复,你从里边取的时候p1,和 p2本来就是一个对象,一个对象从池子里取了两遍。
回复 使用道具 举报


        import java.util.*;
        class Demo
        {
                public static void main(String[] args)
                {
                        HashSet<Person> hs=new HashSet<Person>();
                        Person p1=Person.newPerson("zhangsan01",20);
                        Person p2=Person.newPerson("zhangsan01",20);//传入的对象相同了,被覆盖了
                        Person p3=Person.newPerson("zhangsan04",20);
                        Person p4=Person.newPerson("zhangsan03",25);
                        hs.add(p1);
                        hs.add(p2);
                        hs.add(p3);
                        hs.add(p4);
                        Iterator<Person> it=hs.iterator();
                        while (it.hasNext())
                        {
                                Person p=it.next();
                                System.out.println(p.getName()+"::"+p.getAge());
                        }
                }
        }

        class Person
        {
                private String name;
                private int age;
                //创建对象池 用于存储Person对象
                private static HashSet<Person> objectPool=new HashSet<Person>();

                public Person(String name,int age)
                {
                        this.name=name;
                        this.age=age;
                }
                public String getName()
                {
                        return name;
                }
                public int getAge()
                {
                        return age;
                }
                //定义方法,用于创建Person对象
                public static Person newPerson(String name,int age)
                {
                        for (Person p:objectPool )
                        {
                                //如果对象已经在对象池中存在,则直接返回该对象
                                if(p.name.equals(name)&&p.age==age)
                                        return p;
                        }
                        //如果该对象不存在,则创建新对象,并将该对象添加到对象池中
                        Person p=new Person(name,age);
                        objectPool.add(p);
                        return p;
                }
        }
回复 使用道具 举报
耿鑫 发表于 2012-6-26 17:42
Person p1=Person.newPerson("zhangsan01",20);在对象池里有这个对象了,第二次Person p2=Person.newPerson ...

哦了,明白了,这和覆写对象的hashcode方法和equals方法不一样,对象池本身就是一个不允许元素重复的集合,如果去取两次相同的元素肯定是不能添加到另一个hashset集合中的,知道了和覆写hashcode方法无关就哦了!
回复 使用道具 举报
额,这样你就明白了啊!对象池不允许重复的元素是对的,但是它不允许重复的元素是以哈希值为标准的,如果你覆写hashCode方法,让它成为一个随机值,看相同的元素还能不能加进去,答案是肯定的!这里之所以加不进去是因为它在添加进HashSet的时候调用的是上帝,最顶层父类Object的hashCode方法,这个方法计算hashCode的值是根据对象的全部属性和方法来判断的!具体可以看下老毕的基础教程!!我就不多说了!
回复 使用道具 举报
本帖最后由 耿鑫 于 2012-6-27 09:33 编辑
黄奕豪 发表于 2012-6-27 01:16
额,这样你就明白了啊!对象池不允许重复的元素是对的,但是它不允许重复的元素是以哈希值为标准的,如果你 ...

楼主问的是从对象池中拿出来的元素为什么没有添加进去,从对象池里边拿两个相同的元素肯定是不能添加到另外一个Set当中的,楼主的程序p1,p2不就是对象池中的同一个元素吗?你的意思我明白,如果在Person类中重写了equals 和hashCode方法,让hashCode是随机值的话,newPerson("zhangsan01",20)和newPerson("zhangsan01",20)就是两个不同的对象了,对象池中就是两个不同的元素了,所以从对象池中取的时候也是不同的元素,完全可以加到另一个Set当中,不知道我的理解对不?
我感觉楼主的意思是简单点就是从HashSet对象池中取的元素为什么不能重复放到另一个HashSet中,我认为这和重写hashCode没关系,假如重写了 对象池也就变了,让hashCode是随机值,对象池中就永远没有重复元素了,这也违背了对象池的初衷了。

楼主应该在Person类里重写下hashCode和equals方法,来判断下相等的条件是什么,然后再添加到对象池中,而不是用父类Object的hashCode和equals方法,我想黄兄应该是这个意思。
回复 使用道具 举报
耿鑫 发表于 2012-6-27 09:24
楼主问的是从对象池中拿出来的元素为什么没有添加进去,从对象池里边拿两个相同的元素肯定是不能添加到另 ...

:(好吧!我错了!
回复 使用道具 举报
耿鑫 中级黑马 2012-6-27 09:43:26
8#
黄奕豪 发表于 2012-6-27 09:41
好吧!我错了!

可能我理解错了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马