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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马朱超 中级黑马   /  2013-4-20 19:46  /  2341 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 黑马朱超 于 2013-4-23 23:34 编辑

hashset集合中存入的是对象的引用地址还是对象本身?

11 个回复

倒序浏览
hashset集合中存入的是对象的引用地址。
回复 使用道具 举报
HashSet是基于HashMap实现的,HashSet 底层采用 HashMap 来保存所有元素,它只是封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。
回复 使用道具 举报
java中的Hashset集合中存入的是对象的引用地址。

基本上,每一个对象都有一个默认的散列码,其值就是对象的内存地址。
回复 使用道具 举报
存入的是引用地址
回复 使用道具 举报
存入的是地址,根据hash算法得到的一个元素在内存中的存放地址,这个地址指向该元素在内存的位置,改变时也是改变地址值,不会动那个元素。
回复 使用道具 举报
如果问题未解决,请继续追问,如果问题解决了,请将问题分类改为“已解决”,谢谢
另外相对简单的问题,善用搜索,继续加油
回复 使用道具 举报
存的是对象在堆中的地址,这个地址不会重复。
回复 使用道具 举报
稍后云版块会推出学习过程中问题以及对知识点的领悟收集!会有技术分奖励,敬请期待、多多参与,要注意按照进度收集问题,那样你会事半功倍。
回复 使用道具 举报
前面将一个Set集合扩展成了Map集合,由于这个Set采用了HashSet作为实现类,HashSet会使用Hash算法来保存集合中的每个SimpleEntry元素,因此扩展出来的Map本质上是一个HashMap。

实际上,HashSet和HashMap之间有很多相似之处。对于HashSet而言,系统采用Hash算法决定集合元素的存储位置,这样可以保证快速存、取集合元素;对于HashMap而言,系统将value当成key的"附属物",系统根据Hash算法来决定key的存储位置,这样可以保证快速存、取集合key,而value总是紧随key存储。

在介绍集合存储之前需要指出一点:虽然集合号称存储的是Java对象,但实际上并不会真正将Java对象放入Set集合中,而只是在Set集合中保留这些对象的引用而已。也就是说,Java集合实际上是多个引用变量所组成的集合,这些引用变量指向实际的Java对象。

就像引用类型的数组一样,当把Java对象放入数组中之时,并不是真正把Java对象放入数组中,而只是把对象的引用放入数组中,每个数组元素都是一个引用变量。

对于每个Java集合来说,其实它只是多个引用变量的集合,下面程序可以证明这一点。

程序清单:codes\03\3.1\ListTest.java

    class Apple  
    {  
        double weight;  
        public Apple(double weight)  
        {  
            this.weight = weight;  
        }  
    }  
    public class ListTest  
    {  
        public static void main(String[] args)  
        {  
            // 创建两个Apple对象  
            Apple t1 = new Apple(2.2);  
            Apple t2 = new Apple(1.8);  
            List<Apple> list = new ArrayList<>(4);  
            // 将两个Apple对象放入List集合中  
            list.add(t1);  
            list.add(t2);  
            // 判断从集合里取出的引用变量和原有引用变量是否指向同一个元素  
            System.out.println(list.get(0) == t1);     //①  
            System.out.println(list.get(1) == t2);     //②  
        }  
    }  

上面程序先创建两个Apple对象,其中t1指向第1个Apple对象,t2指向第2个Apple对象。此时系统内存的分配示意图如图3.6所示。

图3.6  内存中包含的两个Apple对象

接下来,程序创建了一个List集合,并定义了一个list变量指向该List集合。因此,程序创建的实际上是一个初始长度为4的ArrayList,也就是说,这个List集合的底层长度为4。

ArrayList底层是基于数组实现的,也就是说,ArrayList底层封装的是数组,每次创建ArrayList时传入的int参数就是它所封装的数组的长度;如果创建ArrayList时没有传入int参数,那么ArrayList的初始长度为10,也就是它底层所封装的数组的长度为10。关于ArrayList更深入的介绍可以参考3.3节。

程序创建了一个初始长度为4的ArrayList之后,接着开始尝试将Java对象放入ArrayList中。这与把Java对象放入数组中是完全相同的效果:系统不会真正把Java对象放入ArrayList中,只是向ArrayList集合中存入这些Java对象的引用。当执行两条add语句之后,系统内存的分配示意图如图3.7所示。

图3.7  将两个Apple对象放入ArrayList集合中
回复 使用道具 举报
所有引用类型保存的都是对象的地址, HashSet是保存了对象的地址的集合, 保存的对象必须是唯一的, 用equals和hashCode确定集合中元素的唯一性
回复 使用道具 举报
breeze 发表于 2013-4-23 21:48
所有引用类型保存的都是对象的地址, HashSet是保存了对象的地址的集合, 保存的对象必须是唯一的, 用equals ...

en ,thx~~~~~~~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马