Set集合本身只定义有不允许重复的存储,Set继承了Colletion的接口,也就是说Set几乎与Collection的操作是对等的。
从实际的开发来看,经常使用到Set集合的框架只有Hibernate,还有一些批量删除这样的操作,但是我们大家一开始还是考虑List接口。
但是对于Set接口最麻烦的问题不在于它的接口特点而在于子类特点,如果从开发的角度来说,常见的是以下三个可能见到的子类:
1.HashSet(无序存放)
-源代码里面有一个HashMap,但是没有使用value,只使用了key
-在HashMap的add()方法中使用了put()方法
-put调用了putval()方法
-putval()里面使用了哈希码
-在整个存储过程中使用了hashCode()的使用
-在进行我们内部的Node类处理时,依然使用了equals()判断key与value内容
-object子类中没有区分出重复元素的问题,是因为这个子类里面并没有提供一个与之相符合的hashCode()和equals()方法,从而默认会去找super的hashCode()方法,而object类中的hashCode()是一个navie类,其中hashCode返回的是由对象存储地址转化得到的值。(注意,String类中重写了)
2.TreeSet:使用的Map集合(SortedMap接口子类)
-里面存放的是TreeMap,其特点是里面的Key是可以排序的,而排序的依据是继承了Comparable(往往会忽略Comparator)。
-在TreeMap之中,对于大小关系判断强制使用了Comparable接口中的compareTo()完成。
-TreeSet中保存的数据必须是Cmparable的子类,在实际开发之中即便使用了集合保存所有的查询结果,但是由于数据表的主键不会重复,所以也就证明这个时候是否进行重复元素的判断是没有任何意义的。
class Member implements Comaprable<Member>{
private String name;
private int age;
@Override
public int compareTo(Member o){
if (this.age >o.age){
return 1;
}else if (this.age <o.age){
return -1;
} else{
//如果不加这一行,那么相同年龄的只会出现一个
return this.name.compareTo(o.name);
}
}
}
3.LinkedHashSet
如果这个时候需要进行连续的保存(FIFO), 这个时候,可以使用另一个子类,这个子类只会在Hibernate中有。之所以可以进行顺序的保存,是因为在进行存储的时候采用的是链表形式完成的。