热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深入解析:Java中的HashSet源码详解

本文详细介绍了Java中HashSet的工作原理及其源码分析。HashSet实现了Set接口,内部通过HashMap来存储数据,不保证元素的迭代顺序,且允许null值的存在。文章不仅涵盖了HashSet的基本概念,还深入探讨了其内部实现细节。

一、HashSet概述:

  • HashSet是Java集合框架中的一个重要类,它实现了Set接口,底层通过HashMap来实现数据存储。HashSet不允许重复元素,但允许null值的存在。
  • HashSet不保证集合中元素的顺序,也不保证顺序在不同的操作后保持不变。此外,HashSet不是线程安全的。
  • 由于HashSet依赖于HashMap,因此了解HashMap的实现对于理解HashSet至关重要。如果你对HashMap的源码还不熟悉,建议先阅读相关资料。

二、HashSet源码分析(基于JDK 8)

1. 类的继承关系

public class HashSet
    extends AbstractSet
    implements Set, Cloneable, Serializable

分析:HashSet继承自AbstractSet抽象类,并实现了Set、Cloneable和Serializable接口。Serializable接口使得HashSet可以被序列化,从而可以将HashSet对象保存到文件或数据库中。

2. 类的属性

// 序列化版本UID
static final long serialVersiOnUID= -5024744406713321676L;

// 底层使用的HashMap实例
private transient HashMap map;

// 用于HashMap中的虚拟值
private static final Object PRESENT = new Object();

3. 构造器

(1)无参构造器

public HashSet() {
    // 默认构造一个空的HashSet,底层使用默认初始容量为16和加载因子0.75的HashMap
    map = new HashMap();
}

(2)基于集合的构造器

public HashSet(Collection c) {
    // 构造一个包含指定集合中所有元素的HashSet
    map = new HashMap(Math.max((int) (c.size() / .75f) + 1, 16));
    addAll(c);
}

(3)指定初始容量和加载因子的构造器

public HashSet(int initialCapacity, float loadFactor) {
    // 指定初始容量和加载因子构造一个空的HashSet
    map = new HashMap(initialCapacity, loadFactor);
}

(4)指定初始容量的构造器

public HashSet(int initialCapacity) {
    // 指定初始容量构造一个空的HashSet,加载因子默认为0.75
    map = new HashMap(initialCapacity);
}

(5)内部构造器(支持LinkedHashSet)

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    // 内部构造器,主要用于支持LinkedHashSet
    map = new LinkedHashMap(initialCapacity, loadFactor);
}

4. 方法详解

(1)iterator方法

public Iterator iterator() {
    // 返回一个迭代器,用于遍历集合中的元素
    return map.keySet().iterator();
}

(2)size方法

public int size() {
    // 返回集合中的元素数量
    return map.size();
}

(3)isEmpty方法

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

(4)contains方法

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

(5)add方法

public boolean add(E e) {
    // 向集合中添加元素,如果集合中已存在该元素则返回false
    return map.put(e, PRESENT) == null;
}

(6)remove方法

public boolean remove(Object o) {
    // 从集合中移除指定元素,如果成功移除则返回true
    return map.remove(o) == PRESENT;
}

(7)clear方法

public void clear() {
    // 清空集合中的所有元素
    map.clear();
}

(8)clone方法

public Object clone() {
    try {
        HashSet newSet = (HashSet) super.clone();
        newSet.map = (HashMap) map.clone();
        return newSet;
    } catch (CloneNotSupportedException e) {
        throw new InternalError();
    }
}

5. Java API方法总结

方法 返回值
boolean add(E e) 如果集合中尚未包含指定元素,则添加该元素并返回true
void clear() 清空集合中的所有元素
Object clone() 返回集合的一个浅表副本
boolean contains(Object o) 如果集合中包含指定元素,则返回true
boolean isEmpty() 如果集合为空,则返回true
Iterator iterator() 返回一个迭代器,用于遍历集合中的元素
boolean remove(Object o) 如果集合中包含指定元素,则移除该元素并返回true
int size() 返回集合中的元素数量

以上是对Java中HashSet的详细解析,希望对你有所帮助。如果有任何问题或建议,欢迎留言讨论。


推荐阅读
  • 本文探讨了在使用JavaMail发送电子邮件时,抄送功能未能正常工作的问题,并提供了详细的代码示例和解决方法。 ... [详细]
  • 本文详细介绍了HashSet类,它是Set接口的一个实现,底层使用哈希表(实际上是HashMap实例)。HashSet不保证元素的迭代顺序,并且是非线程安全的。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • CentOS7通过RealVNC实现多人使用服务器桌面
    背景:公司研发团队通过VNC登录到CentOS服务器的桌面实现软件开发工作为防止数据外泄,需要在RealVNC设置禁止传输文件、访问粘贴板等策略过程&# ... [详细]
  • 本文介绍了如何在 MapReduce 作业中使用 SequenceFileOutputFormat 生成 SequenceFile 文件,并详细解释了 SequenceFile 的结构和用途。 ... [详细]
  • 本文介绍了一种通过设置主题(Theme)来实现快速启动的Android引导页,并详细说明了如何避免因不同屏幕分辨率导致的图片拉伸问题。 ... [详细]
  • 本文详细介绍了Java库com.powsybl.afs.storage中的NodeGenericMetadata.getBooleans()方法,并提供了多个实际应用的代码示例。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 本文介绍了实时流协议(RTSP)的基本概念、组成部分及其与RTCP的交互过程,详细解析了客户端请求格式、服务器响应格式、常用方法分类及协议流程,并提供了SDP格式的深入解析。 ... [详细]
  • 本文探讨了一种统一的语义数据模型,旨在支持物联网、建筑及企业环境下的数据转换。该模型强调简洁性和可扩展性,以促进不同行业间的插件化和互操作性。对于智能硬件开发者而言,这一模型提供了重要的参考价值。 ... [详细]
  • 默认情况下,Java 的克隆机制是浅克隆,即仅复制对象本身而不复制其内部引用的对象。本文将详细介绍如何通过深度克隆来确保对象及其内部引用的对象都能被正确复制。 ... [详细]
  • 尽管Medium是一个优秀的发布平台,但在其之外拥有自己的博客仍然非常重要。这不仅提供了另一个与读者互动的渠道,还能确保您的内容安全。本文将介绍如何使用Bash脚本将Medium文章迁移到个人博客。 ... [详细]
  • 本文详细介绍了如何在Android应用中实现重复报警功能。示例代码可在以下路径找到:https://developer.android.com/samples/RepeatingAlarm/index.html。首先,我们将从Manifest文件开始分析。 ... [详细]
  • SDWebImage第三方库学习
    1、基本使用方法异步下载并缓存-(void)sd_setImageWithURL:(nullableNSURL*)urlNS_REFINED_FOR_SWIFT;使用占位图片& ... [详细]
  • 文章目录python包-requests关于requests包安装和使用pythonrequests请求超时设置工作中遇到的常见问题整理访问https网站,报错cer ... [详细]
author-avatar
刘旭
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有