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方法)。