1.Set
Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类。
在判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现。
HashSet是哈希表结构,主要利用HashMap的key来存储元素,计算插入元素的hashCode来获取元素在集合中的位置;
TreeSet是红黑树结构,每一个元素都是树中的一个节点,插入的元素都会进行排序;
Set集合框架结构:
1.1 HashSet
1. 底层数据结构是哈希表(是一个元素为链表的数组)
2. HashSet其实是用HashMap()来实现的,HashMap()是Map接口的实现类。
调用HashSet的add()方法其实就是调用HashMap()中的put()
Hashset具有如下特点:
不允许出现重复因素;
允许插入Null值;
元素无序(添加顺序和遍历顺序不一致);
线程不安全,若2个线程同时操作HashSet,必须通过代码实现同步;
1.2 TreeSet
1. 底层数据结构是红黑树(是一个自平衡的二叉树)
TreeSet是一个有序的集合,基于TreeMap实现,支持两种排序方式:自然排序和定制排序。
TreeSet是非同步的,线程不安全的。
a:自然排序(元素具备比较性)
让元素所属的类实现Comparable接口,重写其中的compareTo方法
package cn.itcast_03;public class Student implements Comparable{privateString name;private intage;publicStudent() {
super();//TODO Auto-generated constructor stub
}public Student(String name, intage) {
super();this.name =name;this.age =age;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}
@Overridepublic intcompareTo(Student s) {int num = 0;
num= this.age -s.age;int num2 = num == 0 ? this.name.compareTo(s.name) : num;returnnum2;
}
}
b:定制排序(比较器排序,集合具备比较性)
让集合构造方法接收Comparator的实现类对象,在实现类中重写compare()方法
这种方法通过调用集合的带参构造来实现比较
public TreeSet(Comperator comparator)//比较器排序
Comperator 是一个接口,把接口作为参数其实就是需要这个接口的实现类的对象
通过API我们可以得知这个接口中方法的格式,另外,这种需要一个接口的实现类的对象作为参数的情况,开发中我们常常使用匿名内部类的格式
TreeSet ts = new TreeSet(new Comparator() {public intcompare(Student s1,Student s2) {//注意这个三目比较,赋值的优先级最小,==最大,三目中间
int num = s1.getName().length() -s2.getName().length();int num2 = num == 0 ?s1.getName().compareTo(s2.getName()) : num;int num3 = num2 == 0 ? s1.getAge() -s2.getAge() : num2;returnnum3;
}
});
TreeSet具有如下特点:
对插入的元素进行排序,是一个有序的集合(主要与HashSet的区别);
底层使用红黑树结构,而不是哈希表结构;
允许插入Null值;
不允许插入重复元素;
线程不安全;
1.3 LinkHashSet( HashSet+LinkedHashMap )
对于 LinkedHashSet 而言,它继承与 HashSet、又基于 LinkedHashMap 来实现的。LinkedHashSet 底层使用 LinkedHashMap 来保存所有元素,它继承与 HashSet,其所有的方法操作上又与 HashSet 相同,因此LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构造器,底层构造一个 LinkedHashMap 来实现,在相关操作上与父类 HashSet 的操作相同,直接调用父类 HashSet 的方法即可。
总结:
底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
由链表保证元素有序
由哈希表保证元素唯一