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. Sequence(尺取)

    A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, a ...

  2. jenkins 学习记录2

    主题 在之前的学习中(http://www.cnblogs.com/abcwt112/p/6274575.html)我已经学会怎么打包了..这篇文章记录分享我学习如何利用jenkins将打完的包发布到 ...

  3. 【原创】2. MYSQL++之Connect类型

    mysqlpp:: Connect类型主要负责连接事宜,这是在所有开始mysql操作之前必须进行的(这是句废话). 该类型的主要的结果如下所示 mysqlpp::OpeitonalExceptions ...

  4. 数据库SQL优化大总结之 百万级数据库优化方案 【转载】

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  5. 阿帕奇配置本地虚拟站点,XAMPP环境下

    首先利用XAMPP搭建的阿帕奇环境,必须得启动,不能启动的话www.baidu.com 在XAMPP的目录下的apache,打开httpd-vhosts.conf文件 E:\XAMPP\apache\ ...

  6. Ros学习——移动机器人Ros导航详解及源码解析

    1 执行过程 1.运行仿真机器人fake_turtlebot.launch:加载机器人模型——启动机器人仿真器——发布机器人状态 2.运行amcl节点fake_amcl.launch:加载地图节点ma ...

  7. 代理模式 静态代理、JDK动态代理、Cglib动态代理

    1 代理模式 使用代理模式时必须让代理类和被代理类实现相同的接口: 客户端通过代理类对象来调用被代理对象方法时,代理类对象会将所有方法的调用分派到被代理对象上进行反射执行: 在分派的过程中还可以添加前 ...

  8. PCL struct“flann::SearchParams参数错误

    最近在使用PCL的KdTreeFLANN的时候报错:error C2079: “pcl::KdTreeFLANN<PointT>::param_radius_”使用未定义的 struct“ ...

  9. 16.数据类型(data_type)

    CREATE TABLE 语句 CREATE TABLE 语句用于创建数据库中的表. SQL CREATE TABLE 语法 CREATE TABLE 表名称 ( 列名称1 数据类型, 列名称2 数据 ...

  10. 数据库 MySQL 之 基本概念

    数据库 MySQL 之 基本概念 浏览目录 概述 数据库的特点 数据库的分类 选择MySQL的理由 & MariaDB 介绍 下载及安装 SQL介绍 一.概述 1.数据(data) 存储在表中 ...