参考文献:《Java疯狂讲义》(第三版)
Set类
三种实现类:
1、HashSet;
2、TreeSet;
3、EnumSet;
HashSet类
HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能;
特点:
1、不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化;
2、HashSet不是同步的,如果多个线程同时访问一个HashSet,假设有两个或者以上线程同时修改了HashSet必须集合时,则必须通过代码来保证其同步;
3、集合元素值可以是null;
LinkedHashSet类:
LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。
即遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素。
TreeSet类
TreeSet类是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
TreeSet采用红黑树的数据结构来存储集合元素
TreeSet支持两种排序算法:自然排序和定制排序,默认情况下采用自然排序。
知识点:向TreeSet集合中添加元素时,只有第一个元素无须实现Comparable接口(排序用),后面添加的所有元素必须实现Comparable接口。当然这也不是一种好做法,当视图从TreeSet中取出元素时,依然会引发ClassCastException异常。
EnumSet:
专门为枚举类设计的集合类。EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显示或者隐式的指定。EnumSet的集合元素也是指定的。
各Set实现类的性能分析:
HashSet和TreeSet是Set的两个典型实现,两者比较:
HashSet性能总是比TreeSet好(特别是最常用的添加、查询元素等操作),因为TreeSet需要额外的红黑树算法来维护集合元素的次序。
只有当需要一个保持排序的Set时,才应该使用TreeSet。
HashSet子类——LinkedHashSet,对于普通的插入、删除操作,LinkedHashSet比HashSet要略微慢一点,这是由维护链表所带来的额外开销造成的,但由于有了链表,遍历LinkedHashSet会更快。
EnumSet是所有Set实现类中性能最好的,但它只能保存同一个枚举类的枚举值作为集合元素。
Set的三个实现类线程都是不安全的。如果有多个线程同时访问一个Set集合,并且有超过一个线程修改了该Set集合,则必须手动保证该Set集合的同步性能。通常可以通过Collections工具类的synchronizedSortedSet方法来包装Set集合。此操作最好在创建时进行,以防止对Set集合意外的非同步访问。