三种常用Set:HashSet、LinkedHashSet、TreeSet

  set类继承关系:

    

  概述

    Set是对对应Map的一种封装,Set中的元素不可以重复。

    HashSet对应 HashMap、LInkedHashSet对应LinkedHashMap、TreeSet对应TreeMap

   HashSet特点

    1 不保证set的迭代顺序,特别是它不保证该顺序恒久不变;

    2 不允许有重复元素,这是因为HashSet是基于HashMap实现的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个private static final Object PRESENT = new Object();

    3 非线程安全的;

    4 HashSet通过iterator()返回的迭代器是fail-fast的(参考http://www.cnblogs.com/chenssy/p/3870107.html)。

  HashSet源码分析,LInkedHashSet和TreeSet类似

    成员变量

    两个重要的成员变量:map、PRESENT

    1)map:HashSet基于一个HashMap实现;

    2)PRESENT:作为HashMap中的value;

 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;
//定义一个"虚拟"的static final Object对象作为HashMap的value
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

    构造函数

    //构造函数,即新建一个HashMap,默认初识容量为16,加载因子为0.75。
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
。。。

    查找

      HashSet提供了contains(Object o)查看是否包含指定元素的方法,其底层调用的是HashMap.containsKey(Object key)判断是否包含指定key。

     //Set是否含有元素o,即map中是否含有该key
public boolean contains(Object o) {
return map.containsKey(o);
}

    添加

      HashSet提供了add(E e)添加元素的方法,其调用的是底层HashMap中的put(K key, V value)方法,首先判断元素(也就是key)是否存在,如果不存在则插入,如果存在则不插入,这样HashSet中就不存在重复值。

    //如果此set中尚未包含指定元素,则添加指定元素
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

      底层:当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该值确定对象在HashSet中的存储位置。在HashSet中,不能同时存放两个相等的元素,而判断两个元素相等的标准是两个对象通过equals方法比较相等并且两个对象的HashCode方法返回值也相等。

      注意:对于HashSet中保存的对象,请注意正确重写其equals和hashCode方法,以保证放入的对象的唯一性。

    清空与删除

 //如果指定元素存在于此set中,则将其移除
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
} //从此set中移除所有元素
public void clear() {
map.clear();
}

    其他

     //返回此set中的元素的数量
public int size() {
return map.size();
} //如果此set不包含任何元素,则返回 true
public boolean isEmpty() {
return map.isEmpty();
} //返回此 HashSet实例的浅表副本
@SuppressWarnings("unchecked")
public Object clone() {
try {
HashSet<E> newSet = (HashSet<E>) super.clone();
newSet.map = (HashMap<E, Object>) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}

    迭代器

     //返回对此 set中元素进行迭代的迭代器
public Iterator<E> iterator() {
return map.keySet().iterator(); //HashMap.keySet()返回<key, value>对中的key集
}

参考资料

https://www.cnblogs.com/CherishFX/p/4790735.html

Java数据结构-------Set的更多相关文章

  1. Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用

    Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...

  2. JAVA数据结构系列 栈

    java数据结构系列之栈 手写栈 1.利用链表做出栈,因为栈的特殊,插入删除操作都是在栈顶进行,链表不用担心栈的长度,所以链表再合适不过了,非常好用,不过它在插入和删除元素的时候,速度比数组栈慢,因为 ...

  3. Java数据结构之树和二叉树(2)

    从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...

  4. Java数据结构之树和二叉树

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  5. Java数据结构之线性表(2)

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  6. Java数据结构之线性表

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  7. java 数据结构 图

    以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客,主要是在自己理解的基础上进行记录. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示 ...

  8. java 数据结构 队列的实现

    java 数据结构队列的代码实现,可以简单的进行入队列和出队列的操作 /** * java数据结构之队列的实现 * 2016/4/27 **/ package cn.Link; import java ...

  9. java 数据结构 栈的实现

    java数据结构之栈的实现,可是入栈,出栈操作: /** * java数据结构之栈的实现 * 2016/4/26 **/ package cn.Link; public class Stack{ No ...

  10. Java数据结构和算法

    首先,本人自学java,但是只学习了java的基础知识,所以想接下来学习一下数据结构和算法,但是找了很多教材,大部分写的好的都是用c语言实现的,虽然知道数据结构和算法,跟什么语言实现的没有关系,但是我 ...

随机推荐

  1. Oracle - 存储过程、函数、包的使用练习-雇员

    --存储过程范例:得到雇员表 emp 的记录数 begin --说明:若过程中要向外抛异常,请使用 exception when others then raise; 这个抛出的异常在程序里是可以捕获 ...

  2. 判断浏览器环境(QQ,微信,安卓设备,IOS设备,PC微信环境,移动设备)

    判断浏览器环境(QQ,微信,安卓设备,IOS设备,PC微信环境,移动设备) // ===== 判断浏览器环境 ===== // // 判断是否是QQ环境 function isQQ() { retur ...

  3. thinkphp-PHP实现Excel导入 导出功能

    Excel导出 //功能:导出题库模板 public function get_contract_ex() { ob_get_clean(); header("Content-Typ:tex ...

  4. Django2.1集成xadmin管理后台所遇到的错误集锦,解决填坑

    django默认是有一个admin的后台管理模块,但是丑,功能也不齐全,但是大神给我们已经集成好了xadmin后台,我们拿来用即可,但是呢,django已经升级到2.1版本了,xadmin貌似跟不上节 ...

  5. 使用jieba和wordcloud进行中文分词并生成《悲伤逆流成河》词云

    因为词云有利于体现文本信息,所以我就将那天无聊时爬取的<悲伤逆流成河>的评论处理了一下,生成了词云. 关于爬取影评的爬虫大概长这个样子(实际上是没有爬完的): #!/usr/bin/env ...

  6. C++ 虚函数实例

    #include <iostream> using namespace std; //线 class Line { public: Line(float len); ; ; protect ...

  7. Windows下安装配置SQLite和使用的教程

    什么是SQLite SQLite是一款非常轻量级的关系数据库系统,支持多数SQL92标准.SQLite在使用前不需要安装设置,不需要进程来启动.停止或配置,而其他大多数SQL数据库引擎是作为一个单独的 ...

  8. Debug调试文件

    在debug.h中设置g_debug_switch即可控制调试级别. /* debug.c */ #include "debug.h" const char *get_log_le ...

  9. winform中使用webBrowser时如何与JS交互

    最近写一个GEPlugin项目,要用到geWebBrowser与JS进行交互. 这个geWebBrowser的事件 private void geWebBrowser1_DocumentComplet ...

  10. java枚举类型转换为Struts2的select的数据

    枚举类:AppSortEnum.java public enum AppSortEnum { CORE(0, "核心应用"), ENJOYMENT(1, "娱乐应用&qu ...