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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© xuchulong1 中级黑马   /  2012-10-30 20:42  /  2164 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Test2 {

public static void main(String[] args)
{
Collection c = new HashSet();
int p1 = 3;
c.add(p1);
System.out.println(c.contains(p1));
p1 = 10;
System.out.println(c.contains(3));
Iterator  it = c.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
可以看到我们这里把 3 放到了hashset中,然后把p的值从3改成了10,但是我们hash表里面依然是3,所以我们要移除的时候就产生了不能移除的错误,从而会引发内存泄露。

从这个问题,我们深入一点的去探索一下,其实张老师说的貌似并不全对,张老师说hashset里面放的是一个引用,对于引用我们知道是个别名,如果这边改了,那边也会改变,这里是一个变了,另一个没变,从打印的结果我们可以看出来,修改后有了两个值,p1是10,而表里面的是3.怎么会出现两个不同的数字的呢,我想答案只有一个,我们将3放到hashset中去,hashset为又分配了一块空间来存放这个值,这样才能解释后面出现了两个不同的值得现象。当然,一家之言,如果有错误欢迎大家指正






评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

5 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报
许庭洲 发表于 2012-10-31 07:46
值得学习ing!

求加分啊
回复 使用道具 举报
这个和hashCode值有关系,如果你自己写一个Point 类,然后覆盖它的hashcode方法,如果你用基本数据类型的话,原有的hashcode方法会认为如果引用的地址一样的话,那么它的hashcode值是一样的,是无法开辟两个空间的,张老师讲hashSet集合的开创和存储和hashCode息息相关,它会根据hashcode值进行判断。通过查看api接口
hashCode 的常规协定是:

在 Java 应用程序执行期间,在同一对象上多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是对象上 equals 比较中所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么在两个对象中的每个对象上调用 hashCode 方法都必须生成相同的整数结果。
以下情况不 是必需的:如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。
在此它强调是对象,基本数据类型是没有hashcode方法的,也就是说他在add方法是并没有使用到HashSet集合的特性。相反如果你用了对象,如果重写了hashCode方法,那么如果修改后hashcode值不同的话,就一定会开辟新的空间。

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
bhxiaobo 发表于 2012-10-31 10:25
这个和hashCode值有关系,如果你自己写一个Point 类,然后覆盖它的hashcode方法,如果你用基本数据类型的话 ...

应该是这样的我重写equals重新试了一下,的确如此
public class ReflectPoint {
        @Override
        public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + x;
                result = prime * result + y;
                return result;
        }

        @Override
        public boolean equals(Object obj) {
                if (this == obj)
                        return true;
                if (obj == null)
                        return false;
                if (getClass() != obj.getClass())
                        return false;
                ReflectPoint other = (ReflectPoint) obj;
                if (x != other.x)
                        return false;
                if (y != other.y)
                        return false;
                return true;
        }

        private int x;
        public int y;
/*       
        public String str1 = "hellojava";
        public String str2 = "jakdbbbbbizad";
        public String str3 = "hahahaha";
*/       
        public ReflectPoint(int x, int y) {
                super();
                this.x = x;
                this.y = y;
        }
       
        public String toString()
        {
                return x+" : "+y ;
        }
       
}

测试类
public class Test2 {

        public static void main(String[] args)
        {
                Collection c = new HashSet();
                ReflectPoint p1 = new ReflectPoint(3,3);
                ReflectPoint p2 = new ReflectPoint(3,5);
                ReflectPoint p3 = new ReflectPoint(3,3);
               
                c.add(p1);
                c.add(p2);

                System.out.println(p1.hashCode());
                System.out.println(p2.hashCode());
               
                Iterator  it = c.iterator();
                while(it.hasNext())
                {
                        System.out.println(it.next()+"  hashcode:");
                }
                System.out.println(p2.hashCode());

                p2.y = 10;

                Iterator  it1 = c.iterator();
                while(it1.hasNext())
                {
                System.out.println(it1.next()+"  hashcode:");
                }

                System.out.println(p1.hashCode());
                System.out.println(p2.hashCode());
               
                c.remove(p2);
                System.out.println(c.size());
        }
}

打印结果为:
1057
1059
3 : 5
3 : 3
1059
3 : 10
3 : 3
1057
1064
2

可见P2值改变了以后,hash表里的值也跟着改变了。但是移除的时候就不能移除了,这里会有内存的泄漏,这里我想打印hashset中存放的原来的p2的值的hashcode却不知道怎么打印了,还希望帮下忙哈
回复 使用道具 举报
学习了  
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马