一:首先来看看Hashset的继承体系

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable

继承AbstractSet类,实现Set接口

set接口继承Collection接口,所以可以迭代,集合的方法它都有,下面来看一下set接口:

public interface Set<E> extends Collection<E> {
// 集合中元素数量
int size(); // 判断集合是否为空
boolean isEmpty(); //判断是否包含指定元素
boolean contains(Object o); //调用该方法可以产生迭代器,这个方法继承自Iterable接口
Iterator<E> iterator(); //将集合转换为数组,这个方法时集合和数组之间的桥梁
Object[] toArray(); //将集合转换为指定类型的数组
<T> T[] toArray(T[] a); //向集合中添加元素
boolean add(E e); //删除集合中的指定元素
boolean remove(Object o); //判断是否包含指定集合中的所有元素
boolean containsAll(Collection<?> c); //将指定集合中的元素添加到集合中
boolean addAll(Collection<? extends E> c); //保留指定集合中的所有元素,就是集合中其他的元素删除
boolean retainAll(Collection<?> c); //删除指定集合中的所有元素
boolean removeAll(Collection<?> c); //清空集合中所有元素
void clear();
}

集合HashSet元素不可以重复,而且是有序的,因为它的底层维护了HashMap类的key值

    private transient HashMap<E,Object> map;

    private static final Object PRESENT = new Object();  

    public HashSet() {
map = new HashMap<E,Object>();
}

当使用构造器new一个HashSet的对象时,实际上创建了一个HashMap对象。

二:再来看看HashSet类中的方法:

//迭代HashSet中的元素,实际上是迭代HashMap的key值
public Iterator<E> iterator() {
return map.keySet().iterator();
}
//HashSet集合中元素size就是map集合中元素数量
public int size() {
return map.size();
}

  

//判断是否为空,也是判断map是否为空
public boolean isEmpty() {
return map.isEmpty();
}

  

//判断Hashset集合是否包含指定元素就是判断map中是否包含指定的key值
public boolean contains(Object o) {
return map.containsKey(o);
}

  

//向集合中添加元素就是向map中put元素,key就是元素,value是一个常量值
public boolean add(E e) {
return map.put(e, PRESENT)==null;
} private static final Object PRESENT = new Object();

  

//移除指定元素,就是删除map中的key-value映射
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}

 

//清空HashSet集合中元素就是清空map集合
public void clear() {
map.clear();
}

三:总结

其实HashSet类的用法很简单,底层实现就是维护一个Hashmap,Hashset类的元素维护在Hashmap的key位置上,

value是一个常量值,因为Hashmap的key是不可重复的,有序的,所以Hashset也具有这样的特性,在涉及到排序

或者去重等问题时,可以考虑使用Hashset集合。

源码分析五(HashSet的内部实现)的更多相关文章

  1. JDK源码分析(五)——HashSet

    目录 HashSet概述 内部字段及构造方法 存储元素 删除元素 包含元素 总结 HashSet概述   从前面开始,已经分析过集合中的List和Map,今天来介绍另一种集合元素:Set.这是JDK对 ...

  2. 集合源码分析之 HashSet

    一 知识准备 HashSet 是Set接口的实现类,Set存在的最大意义区别于List就是,Set中存放的元素不能够重复,就是不能够有两个相同的元素存放在Set中,那么怎样的两个元素才算是相同的,这里 ...

  3. Vue系列---理解Vue.nextTick使用及源码分析(五)

    _ 阅读目录 一. 什么是Vue.nextTick()? 二. Vue.nextTick()方法的应用场景有哪些? 2.1 更改数据后,进行节点DOM操作. 2.2 在created生命周期中进行DO ...

  4. Android源码分析—深入认识AsyncTask内部机制

    本文转载http://blog.csdn.net/singwhatiwanna/article/details/17596225该博主博文,谢谢该博主提供的好文章! 前言 什么是AsyncTask,相 ...

  5. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

  6. jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解

    $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...

  7. ABP源码分析五:ABP初始化全过程

    ABP在初始化阶段做了哪些操作,前面的四篇文章大致描述了一下. 为个更清楚的描述其脉络,做了张流程图以辅助说明.其中每一步都涉及很多细节,难以在一张图中全部表现出来.每一步的细节(会涉及到较多接口,类 ...

  8. MPTCP 源码分析(五) 接收端窗口值

    简述:      在TCP协议中影响数据发送的三个因素分别为:发送端窗口值.接收端窗口值和拥塞窗口值. 本文主要分析MPTCP中各个子路径对接收端窗口值rcv_wnd的处理.   接收端窗口值的初始化 ...

  9. vuex 源码分析(五) action 详解

    action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...

随机推荐

  1. 赶集网dba石展分享归纳

    字段不要使用null值.查询,索引方面不利.如果是整型,int,仅仅是设置 not null还不够.最好是这种一个默认的值0.为什么? text类型处理性能低于varchar.尽量不要使用text/b ...

  2. Functions: C++'s Programming Modules

    在这一章中要学习以下内容: 函数基础 函数原型 通过value向函数传递参数 设计处理数组的函数 使用const指针参数 设计函数处理文本字符串 设计函数处理结构体 设计函数处理string类型的对象 ...

  3. c语言编程-----指向二维数组的指针

    c中如何返回一个指向二维数组的指针 #include <stdio.h> #include <stdlib.h> #define COUNT 3 typedef int (*M ...

  4. MySQL 入门教程

    目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数据类型 五.使用MySQL数据库 ...

  5. PCL特征点与配准(1)

    关于输入一个具体的物体的点云,从场景中找出与该物体点云相匹配的,这种方法可以用来抓取指定的物体等等,具体的代码的解释如下,需要用到的一些基础的知识,在之前的博客中都有提及,其中用到的一些方法可以翻阅前 ...

  6. Laravel 定时任务

    一 .创建Command文件 php artisan make:console RefreshToken 创建app/Console/Commands 下创建RefreshToken.php 取一个名 ...

  7. JavaScript: The Good Parts

    Chapter 1 Good Parts: JavaScript is an important language because it is the language of the web brow ...

  8. Javascript Notes

    Get started with Programming Javascript中的保留字,但是大部分却没在这个语言中使用.undefined,NaN,Infinity也应该算保留字. abstract ...

  9. Android progressbar条形带背景渐变进度风格进度条

    效果图: 代码如下: <ProgressBar android:id="@+id/progressBar" style="?android:attr/progres ...

  10. Qt中使用的C++知识和技能-你必须要了解的

    如果你不确定在使用Qt编程时自己所掌握的C++知识是否够用,这一节的内容会帮到你.这里给出了Qt自身以及在使用Qt进行编程时涉及到的C++知识,因此,通过阅读本节,你会了解你是否缺少一些C++技能. ...