您的位置:首页 > 其它

Set接口下的 HashSet, LinkedHashSet, TreeSet

2018-03-09 20:04 232 查看
HashSet, LinkedHashSet, TreeSet都属于Set, Set实现了Collection接口。
set的两大特性:>1.无序性:无序性!= 随机性。真正的无序性,指的是存储顺序与添加顺序无关。

>2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。
    Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会接受这两个对象。

HashSet  LinkedHashSet  存储元素时 ,会调用该对象的hashCode()方法得到HashCode值 然后根据哈希值来决定该对象在set中的存储位置。所以他们两个判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等

     注意,如果要把一个对象放入HashSet或者linkedhashset中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对象通过equals方法比较返回true时,其 hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。
而 TreeSet 底层的数据结构是二叉树,但存储位置相对添加顺序也是无序的。
所以说s
4000
et是用来存储无序的,不可重复的元素。

Hashset , LinkedHashSet,  TreeSet 都是线程不同步 线程不安全的
HashSet:1. 无序的,不保证数据写入的顺序。
         2. 集合中可以存入null 但是只能存入一个null。

LinkedHashMap:是HashMap的子类,可以按照添加进Map的顺序实现遍历;
                它的底层也是根据hashcode()的哈希值来进行存储的是无序的, 但是它本身还会生成一张链表来维护写入的顺序,做到按顺序输出。
                它也可以存入null 但是也只能存入一个。
                相对于Hashset ;它是用于频繁的遍历,较少的添加、插入操作。

                HashSet适用于 添加 插入 删除等操作。

TreeSet: 由于treeset要进行排序所以不能存入null 如果存入会报空指针异常 (如果实现了Comparator接口,通过适当的写法,时可以避免出现空指针异常,能够存null)
(可以按照添加进集合中的元素的指定属性进行排序)
>要求TreeSet添加进的元素必须是同一个类的!

        >两种排序方式:
        自然排序:①要求添加进TreeSet中的元素所在的类implements Comparable接口
                 ②重写compareTo(Object obj),在此方法内指明按照元素的哪个属性进行排序
                 ③向TreeSet中添加元素即可。若不实现此接口,会报运行时异常
     定制排序:①创建一个实现Comparator接口的实现类的对象。在实现类中重写Comparator的compare(Object o1,Object o2)方法
                 ②在此compare()方法中指明按照元素所在类的哪个属性进行排序
                 ③将此实现Comparator接口的实现类的对象作为形参传递给TreeSet的构造器中
                 ④向TreeSet中添加元素即可。若不实现此接口,会报运行时异常
        >要求重写的compareTo()或者compare()方法与equals()和hashCode()方法保持一致。

 初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。   这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。 如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。 所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。   所以,Java对于eqauls方法和hashCode方法是这样规定的:1、如果两个对象相同,那么它们的hashCode值一定要相同;2、如果两个对象的hashCode相同,它们并不一定相同    上面说的对象相同指的是用eqauls方法比较。你当然可以不按要求去做了,但你会发现,相同的对象可以出现在Set集合中。同时,增加新元素的效率会大大下降。hashcode这个方法是用来鉴定2个对象是否相等的。 那你会说,不是还有equals这个方法吗? 不错,这2个方法都是用来判断2个对象是否相等的。但是他们是有区别的。 一般来讲,equals这个方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals方法,然后在代码中调用,就可以判断他们是否相等 了。简单来讲,equals方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以 认为只要姓名和性别相等,那么就说这2个对象是相等的。hashcode方法一般用户不会去调用,比如在hashmap中,由于key是不可以重复的,他在判断key是不是重复的时候就判断了hashcode 这个方法,而且也用到了equals方法。这里不可以重复是说equals和hashcode只要有一个不等就可以了!所以简单来讲,hashcode相 当于是一个对象的编码,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比较起来不直观。我们一般在覆盖equals的同时也要 覆盖hashcode,让他们的逻辑一致。举个例子,还是刚刚的例子,如果姓名和性别相等就算2个对象相等的话,那么hashcode的方法也要返回姓名 的hashcode值加上性别的hashcode值,这样从逻辑上,他们就一致了。 要从物理上判断2个对象是否相等,用==就可以了。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐