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中有。之所以可以进行顺序的保存,是因为在进行存储的时候采用的是链表形式完成的。