Set接口

来源:互联网 发布:印度超级联赛直播数据 编辑:程序博客网 时间:2024/06/01 07:26

      Set集合类似一个罐子,一旦把对象扔进Set中,集合里多个对象之间没有明显的顺序。

      Set集合不允许包含相同的元素。如果添加相同元素,怎add()方法返回false。

      Set中判断两个对象是否相同是根据equals()方法进行判断。

       Set接口有HashSet、TreeSet和EnumSet三个实现类。

       一、HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。

        HashSet具有以下特点:

         (1)不能保证元素的顺序,顺序有可能发生变化;

          (2)HashSet不是同步的。如果多个线程同时访问一个HashSet集合,必须通过代码来保证期同步;

         (3)集合元素值可以使null。

        当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()来得到该对象hashCode值,然后根据HashCode值来决定该对象在HashSet中存储位置。如果两个元素通过equals()比较返回true,但它们的hashC()返回值不相等,HashSet将会把它们存储在不同位置,也就可以添加成功。

        HashSet集合判断两个元素相等的标准时两个对象通过equals()比较相等,并且两个对象的hashCode()返回值也相等。

       如果将一个对象放入HashSet中,如果重写该对象的equals(),也要重写其hashCode(),其规则是:如果2个对象通过equals()比较返回true时,这两个对象的hashCode也应该相同。

     为什么不直接使用数组,还需要使用HashSet呢?原因是:数组元素的索引是连续的,而且数组的长度是固定的,无法自由增加数组的长度。而HashSet采用每个元素的hashCode作为其索引,从而可以自由增加HashSet的长度,并可以根据元素的hashCode值来访问元素。因此,当从HashSet中访问元素时,HashSet先通过hashCode()方法计算hashCode值,然后直接到该hashCode对应的位置去取出该元素——这就是HashSet速度很快的原因。

     HashSet中每个能存储元素的”槽位(slot)“通常称为”桶"(bucket),如果有多个元素的hashCode值相同,但它们通过equals()方法比较返回false,就需要在一个“桶”里存放多个元素,从而导致性能下降。

     注意:当向HashSet中添加可变对象时,必须十分小心,如果修改HashSet集合中的对象,可能导致该对象与集合中其他对象相等,从而导致HashSet无法准确访问该对象。

     LinkedHashSet是HashSet的子类,其也是根据hashCode值来决定元素存储位置。但它同时使用链表维护元素的次序,这样元素是以插入的顺序保存的,即当遍历LinkedHashSet时,HashSet将会按元素的添加顺序来访问集合里的元素。

       LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问Set里的全部元素时将由很好的性能,因为它以链表来维护内部顺序。

      二、TreeSet类:是SortedSet接口的唯一实现,可以确保集合元素处于排序状态。

       TreeSet并不是根据元素的插入顺序进行排序,而是根据元素的实际值进行排序的。与HashSet采用hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构对元素进行排序。

原创粉丝点击