Set集合

 

Set集合:无序(元素通过迭代器取出来时的顺序不一定跟存入的顺序一致),元素不可重复,set集合的方法和Collection一致,没有自己特有的方法。它取出元素的方法仅有Iterator一种【list有get和Iterator两种】。

  

  |--hashset:保证元素唯一性的原理:hashset底层是哈希表数据结构。哈希表存储元素时,必须使用元素对象的hashcode方法获取该对象的哈希值,来确定该对象在表中的位置,如果hashcode相同,则会继续判断两个元素的equals方法是否为ture。如果为ture,那么将要存储的对象不会存储到集合中。如果为false则会将hashcode+1顺延存储(hash数据结构的“桶”理论)。为了提高元素唯一性效率,尽量保证元素哈希值不相同,从而尽量少调用equals。

  public int hashCode()

  {   

final int NUM = 38;

   return name.hashCode() + age*NUM;//乘以一个随机数降低重复

  }

注意:当自定义的对象向hashset中存储时,必须覆盖hashcode和equlas两个方法确保唯一性。而在ArrayList中仅仅更具equlas方法去判断。

 

 |--treeset:可以对Set集合中元素进行指定方式的排序。TreeSet集合是通过比较的结果是否为0.如果为0,就代表元素重复。TreeSet集合底层封装的是二叉树结构。

注意:为何可以直接向treeset中存储String而保证其唯一性呢?因为String;已经重写了equlas和hashcode方法。

  

TreeSet集合的排序

       a.自然排序:让原始自身具有可比较性,即自定义对象的类中必须implements Comparable接口,重写Comparable接口的compareTo方法。这种方法有其局限性:a.原始自身所具有的可比较性不是所需要的,比如学生默认是按年龄排序,而我们需要按姓名排序;b.元素也可能本身就不具有可比较性,也就是说没有实现Comparable接口。

      b.集合的比较器:让集合自身具备可比较性。即为TreeSet新建一个比较器类。然后将比较器对象传给TreeSet调用其TreeSet(Comparator<? super E> comparator)构造函数。

   

 两种方法写法上的差异:

     a.自然排序自定义对象类需要Implements Comparable,而集合比较器方法是比较器类需implements Comparator;b.自然排序在所重写的compareTo方法中仅需传一个Object,而集合比较器则需要在所重写的compare方法中传入两个Object。

注意:当二者都存在时以集合比较器为准。

 

TreeSet集合排序的弊端:由于TreeSet不能存在重复的元素,故不能对需要将带有重复对象的一组对象进行排序。

 

总结:当自定义对象类用于封装数据,而且该对象类会产生多个对象,而且他们有可能存储到任意集合中,则该对象类出了描述自身属性和行为外还需要:

a.覆盖equals方法,用于判断两个对象的内容是否相同,用于ArrayList和HashSet;

b.覆盖hashcode方法,用于HashSet集合;

c.给该对象类建立比较方式或者自然排序方式,用于TreeSet,其实compare方法和compareTo方法是用于比较对象。只不过TreeSet这个对象比较方式;

d.覆盖toString方法,仅仅用于定义该对象的自己特有字符串表现形式。 

  

  |---LinkedHashSet:在set集合中自身无序,hashset也无序,treeset需要元素自身或者集合自身具有可比较性才能存储并保证有序,但是由于需要比较过程故效率较低。因此,java提供了LinkedHashSet解决此问题,就是在HashSet基础上融入链表结构。

   

Collection汇总:

       

|--List:有序,可重复【不需要保证元素唯一时】

   |--Vector:jdk1.0,同步,安全,被淘汰【尽量不使用】

   |--ArrayList:查询块,增删慢,非同步【需要频繁查询】

   |--LinkedList:增删快,查询慢,非同步【需要频繁增删】

|--Set:无序,不可重复【需要保证元素唯一时】

   |--HashSet:【不需要排序】

   |--TreeSet:【需要排序】

   |--LinkedHashSet:【既要唯一又要增删】

注:【实在明确不了就用ArrayList】。

看到Arry就是数组,联系脚标;

看到Link就是链表,联系addFirst() addLast() removeLast() removeFirst() getFirst() getLast();

看到Hash就是哈希表,就要覆盖hashCode,equals方法。

看到Tree就是二叉树,就要联系Comparable接口(覆盖CompareTo方法)和Comparator接口(覆盖Compare方法)。