Java Set集合
开发工具与关键技术:MyEclipse 10、java语言、
作者:邓李庆
撰写时间: 2019年5月10日
下面小编给大家讲Set集合,Set集合类似于一个罐子,程序可以依次把多个对象“丢进”Set集合,而Set集合通常不能记住元素的添加顺序。Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加失败,add()方法返回false,且新元素不会被加入。
HashSet类是Set接口的典型实现类,大多数时候使用Set集合时就是使用这个实现类。HashSet类按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet类具有以下特点:
不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化
Hashset不是同步的(不是线程安全的),如果多个线程同时访问一个Hashset,假设有两个或者两个以上线程同时修改了Hashset集合时,则必须通过代码来保证其同步。
集合元素值可以是null,但只能放入一个null。
当向HashSet集合中存入一个元素时,HashSet会调用该对象的HashCode()方法来的到该对象的HashCode值,然后根据该HashCode值决定该对象在HashSet中的存储位置。如果有两个元素通过equals方法比较返回true,但它们的HashCode()方法返回值不相等,HhashSet将会把它们存储在不同的位置,依然可以添加成功
Hashset判断元素是否相等的依据:对象的equals()比较返回false;且HashCode值不相等,判断两个元素不相等;见代码图1:
图1
HashSet类还有一个子类LinkedHashSet,LinkedHashSet集合也是根据元素的HashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序列,这样使得元素看起来是以插入的顺序保存的。也就是说,当遍历LinkedhashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素。
LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问set里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。见代码图2:
图2
Treeset是Sortedset接口的实现类,正如Sortedset名字所暗示的,Treeset可以确保集合元素处于排序状态。与Set集合相比,Treeset还提供了如下几个额外的方法
由于treeset是有序的,也支持comparable和comparator两种排序方式。
HashSet和TreeSet是Set的两个典型实现,如何选择HashSet和TreeSet?
HashSet的性能总是比TreeSet好(特别是最常用的添加、查询元素等操作),因为TreeSet需要额外的红黑树算法来维护集合元素的次序。只有当需要一个保持排序的Set时,才应该使用TreeSet,否则一般都应该使用HashSet。
HashSet还有一个子类:LinkedHashSet,对于普通的插入、删除操作,LinkedHashSet比HashSet要略微慢一点,这是由维护链表所带来的额外开销造成的,但由于有了链表,遍历LinkedHashSet会更快。
Set的实现来HashSet、TreeSet都是线程不安全的。如果有多个线程同时访问一个Set集合,并且有超过一个线程修改了该Set集合,则必须手动保证该Set集合的同步性。通常可以通过Collections工具类的synchronizedSortedSet方法来“包装”该Set集合。