一.介绍

1.HashSet

2.HashSet和HashMap的区别

1.相同点

  • HashSet 内部使用 HashMap 存储元素,对应的键值对的键为 Set 的存储元素,值为一个默认的 Object 对象。
  • HashSet和HashMap都是采用Hash算法来决定其元素的存储
  • 都不是同步的

2.不同点

  • HashSet实现了Set接口

    HashMap实现了Map接口

3.fast-fail

  • 快速失败(fail—fast)在用迭代器遍历一个集合对象时,如果遍历过程中集合对象中的内容发生了修改(增加、删除、修改),则会抛出ConcurrentModificationException
  • 迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变 modCount 的值。每当迭代器使用hasNext()/next() 遍历下一个元素之前,都会检测 modCount 变量是否为expectedmodCount 值,是的话就返回遍历值;否则抛出异常,终止遍历。
  • java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。

二.源码部分

1.基本属性

继承AbstractSet:它实现了Set接口中的大部分函数。从而方便其它类实现Set接口。

Cloneable是标记型的接口,它们内部都没有方法和属性,实现 Cloneable来表示该对象能被克隆

Set 接口中的方法和 Collection 中方法一致的。Set 接口取出方式只有一种, 迭代器 。

java.io.Serializable接口:

可以启用其序列化功能。未实现次接口的类无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
//定义序列化ID
static final long serialVersionUID = -5024744406713321676L;
//存储数据的map
private transient HashMap<E,Object> map; // Dummy value to associate with an Object in the backing Map 与后台映射中的对象关联的虚拟值
private static final Object PRESENT = new Object();

2.构造函数

    /**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
* 构造一个新的空集;HashMap实例具有默认的初始容量(16)和负载因子(0.75)。
*/
public HashSet() {
map = new HashMap<>();
}
    /**
* Constructs a new set containing the elements in the specified collection.
* 构造包含指定集合中的元素的新集合
* The <tt>HashMap</tt> is created with default load factor
* (0.75) and an initial capacity sufficient to contain the elements in
* the specified collection.
* 创建的HashMap带有默认负载因子(0.75)和初始容量,初始容量足以包含指定集合中的元素。
* @param c the collection whose elements are to be placed into this set
* @throws NullPointerException if the specified collection is null
*/
public HashSet(Collection<? extends E> c) {
//?
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
//将集合c加入
addAll(c);
}
    /**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* the specified initial capacity and the specified load factor.
* 建造指定容量和负载因子的空集合
* @param initialCapacity the initial capacity of the hash map
* @param loadFactor the load factor of the hash map
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive
*/
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
    /**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* the specified initial capacity and default load factor (0.75).
* 构造指定初始容量的集合
* @param initialCapacity the initial capacity of the hash table
* @throws IllegalArgumentException if the initial capacity is less
* than zero
*/
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
//构造的是LinkedHashMap,该方法不对外公开,是提供给LinkedHashSet使用的
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

3.contains(Object o)

    public boolean contains(Object o) {
return map.containsKey(o);
}

4.add(E e)

    public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

5.remove(Object o)

public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}

三.总结

  1. HashSet怎么不重复?
  • 通过存储元素的 hashCode 方法和 equals 方法来确定元素是否重复。

HashSet源码学习的更多相关文章

  1. HashSet源码学习,基于HashMap实现

    HashSet源码学习 一).Set集合的主要使用类 1). HashSet 基于对HashMap的封装 2). LinkedHashSet 基于对LinkedHashSet的封装 3). TreeS ...

  2. Dubbo源码学习--注册中心分析

    相关文章: Dubbo源码学习--服务是如何发布的 Dubbo源码学习--服务是如何引用的 注册中心 关于注册中心,Dubbo提供了多个实现方式,有比较成熟的使用zookeeper 和 redis 的 ...

  3. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

  4. 死磕Java之聊聊HashSet源码(基于JDK1.8)

    HashSet的UML图 HashSet的成员变量及其含义 public class HashSet<E> extends AbstractSet<E> implements ...

  5. mybatis源码学习:插件定义+执行流程责任链

    目录 一.自定义插件流程 二.测试插件 三.源码分析 1.inteceptor在Configuration中的注册 2.基于责任链的设计模式 3.基于动态代理的plugin 4.拦截方法的interc ...

  6. Spring5.0源码学习系列之浅谈BeanFactory创建

    Spring5.0源码学习系列之浅谈BeanFactory创建过程 系列文章目录 提示:Spring源码学习专栏链接 @ 目录 系列文章目录 博客前言介绍 一.获取BeanFactory主流程 二.r ...

  7. Spring5.0源码学习系列之浅谈循环依赖问题

    前言介绍 附录:Spring源码学习专栏 在上一章的学习中,我们对Bean的创建有了一个粗略的了解,接着本文浅谈Spring循环依赖问题,这是一个面试比较常见的问题 1.什么是循环依赖? 所谓的循环依 ...

  8. Java并发包源码学习系列:线程池ThreadPoolExecutor源码解析

    目录 ThreadPoolExecutor概述 线程池解决的优点 线程池处理流程 创建线程池 重要常量及字段 线程池的五种状态及转换 ThreadPoolExecutor构造参数及参数意义 Work类 ...

  9. JUC源码学习笔记5——线程池,FutureTask,Executor框架源码解析

    JUC源码学习笔记5--线程池,FutureTask,Executor框架源码解析 源码基于JDK8 参考了美团技术博客 https://tech.meituan.com/2020/04/02/jav ...

随机推荐

  1. Hive实现网站PV分析

    原文链接: https://www.toutiao.com/i6773241257528394248/ 之前我们做过<java mapreduce实现网站PV分析>,这次我们可以用hive ...

  2. SYCOJ2205超级百钱百鸡

    题目-超级百钱百鸡 (shiyancang.cn) 百钱百鸡的加强版 百钱百鸡的话,因为是有范围,所以挨个挨个尝试即可,确定两个,即可确定第三个. 超级百钱百鸡,通过题目的描述,最后可以得到一个二元的 ...

  3. 【洛谷】P1067 多项式输出

    原题链接:P1067 多项式输出 题目分析:学长推荐的OJ网站 --洛谷,发现挺好用的还可以下载提交出错的数据. 废话就不多说了,这道题属于基础题.提交出错主要是因为一些小细节不到位,这里就不一一赘述 ...

  4. Ubuntu 18.04 server安装+搭建Seacms v10.1网站

    0x00 写在前面 以前我天真的认为,ubuntu Desktop会安装了,server就无所谓了,其实完全不然,server还是有一些坑点的. 之所以选择Seacms搭建网站,是因为这个SeaCMS ...

  5. 《剑指offer》面试题17. 打印从1到最大的n位数

    问题描述 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数.比如输入 3,则打印出 1.2.3 一直到最大的 3 位数 999. 示例 1: 输入: n = 1 输出: [1,2,3,4,5 ...

  6. VScode远程连接服务器

    VScode远程连接服务器 1.远程服务器安装rmate,在远程服务器上执行以下操作 wget https://raw.githubusercontent.com/sclukey/rmate-pyth ...

  7. WSL删除子系统后无法重装

    问题 WSL卸载后安装error 解决办法 UWP应用卸载后没有删除目录下的文件 C:\Users\wwwfe\AppData\Local\Packages路径下删除就可以了 再次安装会卡顿很久,可能 ...

  8. vector自实现(一)

    vector.h: #ifndef __Vector__H__ #define __Vector__H__ typedef int Rank; #define DEFAULT_CAPACITY 3 t ...

  9. golang中文件和路径用法

    package main import ( "fmt" "io/fs" "io/ioutil" "os" "p ...

  10. Java 后台线程介绍

    一  是啥? package com.aaa.threaddemo; /* * 一 Java后台线程? * 守护线程--也称"服务线程",他是后台线程, * 它有一个特性,即为用户 ...