12
返回列表 发新帖
楼主: silver_xie

[SCJP] 不明白hashSet.remove(o)如果o的属性被该了,就失败

[复制链接]
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
11#
发表于 2008-2-15 21:53 | 只看该作者
不知道这样理解对不对

由于这道题里面,由于hashcode的特殊性,也就是说是严格跟着 i 走的,所以,一旦k2的 i 改变了,就会被Set认为不是原来的那个k2所指向的对象了(因为HashSet的remove是使用的HashMap的remove,HashMap是使用hashcode来判断的,当然不管怎么样,肯定会判定两个对象是否相等了),所以remove的时候就找不到,并且返回了false

这是我重新整理后的代码:

import java.util.*;

class KeyMaster {
        public int i;

        public KeyMaster(int i) {
                this.i = i;
        }

        public boolean equals(Object o) {
                return i == ((KeyMaster) o).i;
        }

        public int hashCode() {
                return i;
        }
}

public class MapIt {
       
        public static void main(String[] args) {
               
                Set<KeyMaster> set = new HashSet<KeyMaster>();

                KeyMaster k1 = new KeyMaster(1);

                KeyMaster k2 = new KeyMaster(2);

                set.add(k1);
                set.add(k1);
                set.add(k2);
                set.add(k2);
               
                System.out.println("Before All, size = " + set.size());

                k2.i = 1;

                System.out.println("After modify k2, size = " + set.size());

                set.remove(k1);

                System.out.println("After remove k1, size = " + set.size());

                boolean flag = set.remove(k2);

                System.out.println("After remove k2, size = " + set.size());
                System.out.println("flag = " + flag);
        }
}

打印结果很明显,就是false。

终于解释通了。

使用道具 举报

回复
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
12#
 楼主| 发表于 2008-2-16 17:23 | 只看该作者
可是我忽然想起来一个问题,你打印出来所有set的值,你会发现,k2=1以后set的值也跟着变了。。。。我的疑惑也在这里。。。。

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
13#
发表于 2008-2-16 19:03 | 只看该作者
什么意思?

使用道具 举报

回复
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
14#
 楼主| 发表于 2008-2-16 20:12 | 只看该作者

我打印的结果,注意set的两个值的变化

k1=KeyMaster@1
k2=KeyMaster@2

after add4 size=2:
[KeyMaster@2, [email=KeyMaster@1]KeyMaster@1[/email]]    set的值
after k2.i=1 size=2:
[KeyMaster@1, KeyMaster@1]
k1=KeyMaster@1
k2=KeyMaster@1
after remove(k1) twice!!! size=1:
[KeyMaster@1]                          set的值
k1=KeyMaster@1
k2=KeyMaster@1
after remove(k2) size=1
[KeyMaster@1]                       set的值也随着i的改变而变了。。。。。跟k2的值一样变了。。所以我认为可以从set删除k2...
k1=KeyMaster@1
[email=k2=KeyMaster@2]k2=KeyMaster@2[/email]                  
after k2.i=2 size=0:
[]

[ 本帖最后由 silver_xie 于 2008-2-16 20:15 编辑 ]

使用道具 举报

回复
论坛徽章:
43
ITPUB元老
日期:2007-01-14 09:32:112011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:56管理团队成员
日期:2011-05-07 01:45:08开发板块每日发贴之星
日期:2011-08-29 01:01:012012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:182012新春纪念徽章
日期:2012-02-13 15:11:18
15#
发表于 2008-2-16 23:36 | 只看该作者
FYI:

    Please note the time when the hashCode() method of k1 and k2 were called.

    o. create k1, k2, which k1.i=1, k2.i=2

    o. add k1 to set, k1.hashCode() will be called, so the set find a proper place according to k1's hashCode, a.k.a. "1".

    o. add k2 to set, k2.hashCode() will be called, it is "2", so the set find another place for k2.

    o. change k2.i=1, watch out here, the "place" where k2 reside in the set will NOT change! there is NO dynamic duplicate check nor event notification in set.

    o. delete k1, k1.hashCode() will be called once again. because the nature of set, the set will NOT search through all the background hashmap to delete all object which has "1" as hashcode. so there will be ONLY one object being deleted. k2 will NOT be deleted althought it DOES has a hashcode=1, but it's place in the set is according to "2".

    o. now there is only k2 in the set, which's Key place in the set is "2", although in the mean time it has a hashcode "1".

    o. trying to delete k2, this time k2.hashCode() will be called again, but there is not such object in the set with "1" as key, so deletion FAILED.

    o. change k2.i=2

    o. try to delete k2 again, this time we got a "2" from k2.hashCode(), so we can directly find the k2 object in the set, because there IS a key ojbect in the coressponding place to "2". so deletion SUCCESSED.

使用道具 举报

回复
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
16#
 楼主| 发表于 2008-2-17 10:20 | 只看该作者
pretty complicant.......need time to comprendre, thanks very much!!!!!!!!!!!!


  but it seems that k2.i=anything will not change the set ,only these methods for set can....right?and only these methods will call hashCode()........so....that is the point!!!


thanks!!!!!!!!!!!!!!!!!!!!!1

[ 本帖最后由 silver_xie 于 2008-2-17 10:24 编辑 ]

使用道具 举报

回复
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
17#
 楼主| 发表于 2008-2-17 10:25 | 只看该作者
and the cotents of the set is not the key! I only printed the contents out, not the key ,so the result is making me puzzled....................right?

使用道具 举报

回复
论坛徽章:
16
授权会员
日期:2005-11-22 09:32:00茶鸡蛋
日期:2012-05-28 17:27:32双黄蛋
日期:2012-05-19 23:10:38ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28ITPUB学员
日期:2011-10-09 08:54:30ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47ITPUB9周年纪念徽章
日期:2010-10-08 09:34:022010新春纪念徽章
日期:2010-01-04 08:33:08生肖徽章2007版:龙
日期:2009-05-26 18:16:32ITPUB元老
日期:2008-04-22 10:23:44
18#
发表于 2008-2-17 10:47 | 只看该作者
原帖由 greenflute 于 2008-2-16 23:36 发表
FYI:

    Please note the time when the hashCode() method of k1 and k2 were called.

    o. create k1, k2, which k1.i=1, k2.i=2

    o. add k1 to set, k1.hashCode() will be called, so the set find a proper place according to k1's hashCode, a.k.a. "1".

    o. add k2 to set, k2.hashCode() will be called, it is "2", so the set find another place for k2.

    o. change k2.i=1, watch out here, the "place" where k2 reside in the set will NOT change! there is NO dynamic duplicate check nor event notification in set.

    o. delete k1, k1.hashCode() will be called once again. because the nature of set, the set will NOT search through all the background hashmap to delete all object which has "1" as hashcode. so there will be ONLY one object being deleted. k2 will NOT be deleted althought it DOES has a hashcode=1, but it's place in the set is according to "2".

    o. now there is only k2 in the set, which's Key place in the set is "2", although in the mean time it has a hashcode "1".

    o. trying to delete k2, this time k2.hashCode() will be called again, but there is not such object in the set with "1" as key, so deletion FAILED.

    o. change k2.i=2

    o. try to delete k2 again, this time we got a "2" from k2.hashCode(), so we can directly find the k2 object in the set, because there IS a key ojbect in the coressponding place to "2". so deletion SUCCESSED.


明了了,很牛;

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
19#
发表于 2008-2-17 14:09 | 只看该作者
所以说每一个place都是在add以后被唯一标识成对象的place,解铃还需系铃人,得通过hashcode得到当初放到set里的那个对象,才能将该对象从对应的place取出。

解脱了。

使用道具 举报

回复
论坛徽章:
53
2010新春纪念徽章
日期:2010-03-01 11:19:062012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25版主1段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
20#
发表于 2008-2-18 09:54 | 只看该作者
原帖由 silver_xie 于 2008-2-15 18:05 发表

啊?这是什么意思???


看看hashset的源代码……

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表