Set集合通常不能记住元素添加的顺序,其他的操作和它的父接口基本相同。只是行为上有细微的差别,Set集合不能包含相同的元素。如果尝试添加相同的元素,调用add()方法将返回false,且新元素不能被加入容器。

下面是Set接口的三个实现类,将一一介绍:

1. HashSet

HashSet 类具备以下特征:

1. 不能保证元素的排列顺序,可能和添加的顺序不相同,也有可能会发生变化。
2. HashSet不是线程安全的,如果多个线程同时访问HashSet,假设有两个以上的线程修改了HashSet集合时,在程序中必须要做同步处理。
3. 集合元素值可以是null。

在源码中,HashSet的实现调用HashMap的

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L; private transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object(); public HashSet() {
map = new HashMap<>();
}
... //省略其他源码
}

  也就是说,当想HashSet中存入一个对象时,将调用该对象的hashCode()方法来的到该对象的hashCode值,然后根据hashCode值来得到该对象在HashSet中的位置。如果两个对象的hashCode值不同,就算是同一个对象,HashSet也会将他们存放在不同的位置,也就是说,HashSet集合判断两个元素相等的标准是两个对象通过调用equals()方法返回true,并且两个对象的hashCode()方法返回值也相等。因此,当我们在把自定义的对象放入HashSet的时候,都需要重写这个对象发equals()方法和hashCode()方法,重写hashCode方法的规则如下:

  1. 在程序运行中,同一个对象多次调用hashCode()方法的返回是一致的。
  2. 当两个对象的equals()方法返回为true时,hashCode()方法的返回值也应该相等。
  3. equals()方法中用作比较标准的实例变量,都应该用于计算hashCode值。

2. LinkedHashSet

  LinkedHashSet是HashSet的子类,它也是根据元素的hashCode值来计算元素的存储位置的,并且同时使用链表来维护元素的次序,这样使得元素看起来像是有序的(插入顺序),当我们遍历LinkedHashSet中的元素时,将按照元素的插入顺序来访问集合中的元素。
  LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet,但是迭代Set中的所有的元素时,会有较好的性能,因为它是以链表来维护元素的顺序的。

3. TreeSet

  • TreeSet是SortedSet接口的实现类,如名所示,TreeSet中的元素时有序的(大小序,而不是插入序)。

  • 与HashSet集合采用hashCode算法来决定元素的存储位置不同,TreeSet采用的是红黑树的数据结构来存储集合元素。但是TreeSet集合中的元素时按照上面规则来排序的呢?目前主持两种排序方式:

    1. 自然排序:加入TreeSet中的对象都实现Comparable接口,重写compareTo(Object obj)方法。同时需要保证加入TreeSet的而元素时同一类对象。
    2. 定制排序:加入TreeSet中的对象都实现Comparator接口,重写compare(T o1,T o2)方法。

4. EnumSet

  • EnumSet是一个专为枚举类型设计的集合类,EnumSet中的所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet枚举类型的时候显式或者隐式的指定。EnumSet集合的元素也是有序的,顺序是枚举定义的类型。
  • EnumSet的内部以向量的形式存储,这样占用的空间小,效率高。EnumSet中不允许加入null值。

总结:

各Set实现类的性能分析

  1. HashSet和TreeSet是Set接口的两个典型的实现,如何选择呢?HashSet的性能总是比TreeSet好(特别是频繁的添加,查询操作),因为TreeSet需要额外的红黑树算法来维护集合的次序,只有需要集合有序的时候才使用TreeSet,否则都使用HashSet。
  2. HashSet 和其子类LinkedHashSet,对于普通的插入,删除操作,LinkedHashSet比HashSet要慢一些,因为LinkedHashSet需要维护链表额外开销,但是当需要遍历整个容器时,LinkedHashSet会更快。
  3. EnumSet是这几个实现当中性能最好的,但是EnumSet集合中只能存放枚举类的枚举值。

  注:Set接口中的所有实现HashSet、TreeSet、EnumSet、LinkedHashSet都不是线程安全的,当有两个以上线程同时修改时,必须在程序中手动实现同步性(通常可以使用Collections工具类中的synchronizedSortedSet方法来包装Set集合,最好是在创建的时候设置)。

java集合之Set接口的更多相关文章

  1. Java集合之Collection接口

    java的集合分为三大接口,分别是Collection,Map,Iterator,集合接口和类在java.util包中,此次主要介绍三大接口之一的Collection接口. 一些Collection允 ...

  2. Java集合及LIst接口

    一.集合的概念 1.概述: 在学习集合前,先回忆一下数组的一个特征---数组有固定的长度,定义一个数组: int[] array = new int[]; 而针对数据长度可变的情况,产生了集合, ja ...

  3. Java集合框架——Map接口

    第三阶段 JAVA常见对象的学习 集合框架--Map集合 在实际需求中,我们常常会遇到这样的问题,在诸多的数据中,通过其编号来寻找某一些信息,从而进行查看或者修改,例如通过学号查询学生信息.今天我们所 ...

  4. Java集合框架——Set接口

    第三阶段 JAVA常见对象的学习 集合框架--Set接口 List集合的特点是有序的,可重复的,是不是存在这一种无序,且能保证元素唯一的集合呢?(HashSet )这就涉及到我们今天所要讲的Set集合 ...

  5. Java集合框架——List接口

    第三阶段 JAVA常见对象的学习 集合框架--List接口 按照集合框架的继承体系,我们先从Collection中的List接口开始学习 (一) 概述及功能(ArrayList演示) (1) 概述 L ...

  6. Java集合框架之接口Collection源码分析

    本文我们主要学习Java集合框架的根接口Collection,通过本文我们可以进一步了解Collection的属性及提供的方法.在介绍Collection接口之前我们不得不先学习一下Iterable, ...

  7. Java集合框架Map接口

    集合框架Map接口 Map接口: 键值对存储一组对象 key不能重复(唯一),value可以重复 常用具体实现类:HashMap.LinkedHashMap.TreeMap.Hashtable Has ...

  8. Java集合框架的接口和类层次关系结构图

    Collection和Collections的区别 首先要说的是,"Collection" 和 "Collections"是两个不同的概念: 如下图所示,&qu ...

  9. Java集合中Map接口的使用方法

    Map接口 Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value: Map中的键值对以Entry类型的对象实例形式存在: 建(key值 ...

  10. java集合_collection子接口 list的特有方法,ArrayList类体现

    /* Collection |--List:元素是有序的,元素可以重复.因为该集合体系有索引. |--ArrayList:底层的数据结构使用的是数组结构.特点:查询速度很快.但是增删稍慢.线程不同步. ...

随机推荐

  1. [原创]Java项目统一UTC时间方案

    Java项目统一UTC时间方案 作者:Gods_巨蚁 引言 近期团队的个别项目在进行框架升级后,部分时间值存在8小时误差,原因是错误的将数据库中的时间数据理解成了UTC时间(旧版本认为是北京时间) 考 ...

  2. 页面布局整理(基于scss)

    页面开发步骤: 1.全局reset.设置基础背景色.设置基础字体样式 2.全局布局页面结构,meta 标签引入 3.按钮等相同的样式,用scss提前写好一份公用,渐变等 border-radius b ...

  3. LCS(详解)

    一,问题描述 给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence).比如字符串1:BDCABA:字符串2:ABCBDAB 则这两个字符串的最长公共子序列长 ...

  4. Python模块及其导入

    一.模块 1.模块的定义: 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少, 很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件 ...

  5. Pacemaker实现双机热备

    在互联网高速发展的今天,尤其在电子商务的发展,要求服务器能够提供不间断服务.在电子商务中,如果服务器宕机,造成的损失是不可估量的.要保证服务器不间断服务,就需要对服务器实现冗余.在众多的实现服务器冗余 ...

  6. 设置html页面不被浏览器缓存

    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" ...

  7. codeforces:Helga Hufflepuff's Cup

    题目大意:有一个包含n个顶点的无向无环连通图G,图中每个顶点都允许有一个值type,type的范围是1~m.有一个特殊值k,若一个顶点被赋值为k,则所有与之相邻的顶点只能被赋小于k的值.最多有x个顶点 ...

  8. 如何在局域网架设FTP(特别简单方便)

    https://files.cnblogs.com/files/wlphp/FTPserver.zip 在我上传的博客园文件下载下来 启动服务,设置账号密码(注意一定要关闭防火墙)

  9. Linux常用基本命令 1

    useradd 创建用户. password 修改密码. date 查看时间 man date 帮助文档.f往后翻 b往前翻 q退出.软修改 man hwclock 修改硬件时钟, cal 查看日历 ...

  10. 记一篇Python学习的简易版教程

    廖雪峰的教学博客https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143178 ...