HashSet 无序集合类

  • 实现了Set接口
  • 内部通过HashMap实现
// HashSet
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L; //重要:HashMap HashSet就是通过HashMap保存数据, HashSet的值就是HashMap的key
private transient HashMap<E,Object> map; // 使用transient修饰不会被序列化 //HashMap 为<key, value>的键值对, 既然HashSet的值就是HashMap的key, 那么HashMap的值呢,当然就是这个PRESENT,HashMap所有的value都是同一个对象
private static final Object PRESENT = new Object(); // 默认构造函数,创建一个HashMap对象
public HashSet() {
map = new HashMap<>();
} //将一个已知的collection转换为HashSet
public HashSet(Collection<? extends E> c) {
//Collection<? extends E> c 限制了类型上限为E,也就是c只能是E类型或E的子类,防止参数是非Set类型
//如果没有指定HashMap的capacity, 那么默认的就是16
//根据 threshold = capacity * loadFactor, 可以计算出 capacity
//Math.max((int) (c.size()/.75f) + 1, 16) 这个意思就是capacity如果没超过16, 那么就直接使用默认的16
// 容量设置为4/3倍
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
//将已知的collection转换为HashSet的方法
//addAll方法是HashSet的父类AbstractCollection的方法,为了便于阅读,会将代码粘贴在下面
addAll(c);
}
// 带有初始容量和因子的构造函数
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
} public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
} HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
} //addAll方法是HashSet的父类AbstractCollection的方法
public boolean addAll(Collection<? extends E> c) {
boolean modified = false; // 只要添加了元素就返回true
for (E e : c)
//此处的add方法由HashSet重写实现
if (add(e))
modified = true;
return modified;
} //HashSet的核心方法来了, 没错,就这么简单
public boolean add(E e) {
//应证了上面所说的key为HashSet的值
return map.put(e, PRESENT)==null;
} //剩下这些方法都是跟Map相关的了,只要熟悉了HashMap, 那就太简单了,就不说了
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
} public void clear() {
map.clear();
} }

补充

泛型

泛型的上限通配符<? extends T>

<? extends T>是 Upper Bound(上限) 的通配符,用来限制元素的类型的上限,比如  

List<? extends Fruit> fruits;
表示集合中的元素类型上限为Fruit类型,即只能是Fruit或者Fruit的子类。

泛型的下限通配符<? super T>

<? super E> 是 Lower Bound(下限) 的通配符 ,用来限制元素的类型下限,比如

List<? super Apple> apples;
表示集合中元素类型下限为Apple类型,即只能是Apple或Apple的父类。

参考

java集合-HashSet源码解析的更多相关文章

  1. Java集合-ArrayList源码解析-JDK1.8

    ◆ ArrayList简介 ◆ ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAcc ...

  2. Java集合---LinkedList源码解析

    一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clo ...

  3. java集合类型源码解析之ArrayList

    前言 作为一个老码农,不仅要谈架构.谈并发,也不能忘记最基础的语言和数据结构,因此特开辟这个系列的文章,争取每个月写1~2篇关于java基础知识的文章,以温故而知新. 如无特别之处,这个系列文章所使用 ...

  4. java集合-HashMap源码解析

    HashMap 键值对集合 实现原理: HashMap 是基于数组 + 链表实现的. 通过hash值计算 数组索引,将键值对存到该数组中. 如果多个元素hash值相同,通过链表关联,再头部插入新添加的 ...

  5. java集合类型源码解析之PriorityQueue

    本来第二篇想解析一下LinkedList,不过扫了一下源码后,觉得LinkedList的实现比较简单,没有什么意思,于是移步PriorityQueue. PriorityQueue通过数组实现了一个堆 ...

  6. Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap

    声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...

  7. 【java集合框架源码剖析系列】java源码剖析之HashSet

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...

  8. Java集合框架源码(二)——hashSet

    注:本人的源码基于JDK1.8.0,JDK的版本可以在命令行模式下通过java -version命令查看. 在前面的博文(Java集合框架源码(一)——hashMap)中我们详细讲了HashMap的原 ...

  9. 【java集合框架源码剖析系列】java源码剖析之TreeSet

    本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...

随机推荐

  1. javascript放大镜效果

    JS实现放大镜效果 首先我们先设想一下放大镜效果 1.当鼠标进入小盒子的时候,把大图片显示出来 2.当指定移动区域的时候,显示当前放大区域(放大效果) 3.鼠标移除我们让它消失 一.实现页面布局HTM ...

  2. C语言字符/字符串相关函数收藏

    字符串的声明与使用 定义一个可变的字符串: char ch[]={"123456abc"}; char ch2[5]={"123456789"}; //会出现警 ...

  3. java maven项目update project默认编译器1.5问题解决

    解决办法一:在项目中的pom.xml指定jdk版本,如下 <build> <plugins> <plugin> <groupId>org.apache. ...

  4. Spring Cloud Eureka 常用配置详解,建议收藏!

    前几天,栈长分享了 <Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!>,今天来分享下 Spring Cloud Eureka 常用的一些参数配置及说 ...

  5. Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!

    Spring Cloud 的注册中心可以由 Eureka.Consul.Zookeeper.ETCD 等来实现,这里推荐使用 Spring Cloud Eureka 来实现注册中心,它基于 Netfl ...

  6. 消除点击连接或者按钮或者执行onclick事件时出现的边框

    css中添加 *:not(input) { font-family: sans-serif; font-size-adjust: none; -webkit-user-select: none; -w ...

  7. 在Windows上使用Docker运行.NetCore

    今天我们来说下如何在windows下使用docker运行.net core,既然是docker,那么我们首先得在windows上安装docker. 在Windows安装 docker 有两种选择 :1 ...

  8. 前端笔记之JavaScript面向对象(二)内置构造函数&相关方法|属性|运算符&继承&面向对象

    一.复习 1.1复习上下文 函数的调用方式 上下文 fun() window obj.fun() obj box.onclick = fun box setInterval(fun,1000) set ...

  9. .Net Framework项目引用.NetStandard标准库出现版本冲突解决办法

    今天在工作中出现一个引用问题,害我找问题找了很久.起因是在一个Winform项目下需要引用一个.NetStandard标准库,标准库引用了System.ComponentModel.Annotatio ...

  10. jQuery获取或设置元素的宽度和高度

    jQuery获取或设置元素的宽度和高度: 可使用以下3种方法: 1,jQuery width() 和 height() 方法: 2,innerWidth() 和 innerHeight() 方法: 3 ...