前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文搞懂HashSet类的底层实现原理

一文搞懂HashSet类的底层实现原理

原创
作者头像
喵手
发布2023-11-27 00:03:40
2780
发布2023-11-27 00:03:40
举报
文章被收录于专栏:Java进阶实战

哈喽,各位小伙伴们,你们好呀,我是喵手。

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

在 Java 中,集合是非常重要的一部分,它们可以简化代码编写,提高代码效率。Java 提供了许多集合类,其中 HashSet 类是一种非常常用的集合类。本文将对 HashSet 类进行详细介绍。

摘要

本文将对 Java 中的 HashSet 类进行介绍。首先,我们将介绍 HashSet 类的简介和源代码解析,然后提供一些实际应用场景案例。接着,我们将对 HashSet 类的优缺点进行分析,以及类代码方法的介绍。最后,我们会提供一些测试用例,全文小结和总结。

HashSet类

简介

HashSet 类是 Java 中的一种集合类,它继承了 AbstractSet 类,实现了 Set 接口。HashSet 类可以存储不同类型的数据,而且元素是无序的,元素的值可以为 null。在 HashSet 中,每个元素都必须是唯一的,并且它们是通过哈希表存储的。HashSet 类使用哈希算法来计算元素的索引位置。

HashSet 类有以下几个重要的方法:

  • add(Object obj):将元素添加到集合中。
  • clear():清空集合中的所有元素。
  • contains(Object obj):判断集合中是否包含指定的元素。
  • isEmpty():判断集合是否为空集。
  • remove(Object obj):从集合中删除指定的元素。
  • size():返回集合中的元素个数。

源代码解析

HashSet 类的源代码解析可以分为以下几个部分:

  • 成员变量
  • 构造方法
  • 类方法

成员变量

HashSet 类的成员变量如下:

代码语言:java
复制
// 存储元素的哈希表
private transient HashMap<E,Object> map;

// 存储创建 HashSet 时指定的默认大小(容量为16)和负载因子(0.75)
private static final Object PRESENT = new Object();

其中,map 变量存储了 HashSet 中的所有元素,这些元素是存储在一个哈希表中的。PRESENT 变量存储了一个 Object 对象,该对象在向 HashSet 中添加元素时使用。

在这里插入图片描述
在这里插入图片描述

构造方法

HashSet 类有多个构造方法:

代码语言:java
复制
public HashSet() {
    map = new HashMap<>();
}

public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<>(initialCapacity, loadFactor);
}

public HashSet(int initialCapacity) {
    map = new HashMap<>(initialCapacity);
}

这些构造方法可以根据不同的情况创建 HashSet 对象。例如,第一个构造方法创建默认的 HashSet 对象,第二个构造方法创建一个包含指定 Collection 中所有元素的 HashSet 对象。

在这里插入图片描述
在这里插入图片描述

类方法

HashSet 类的常用方法如下:

代码语言:java
复制
// 添加元素
public boolean add(E e)

// 移除元素
public boolean remove(Object o)

// 返回集合的大小
public int size()

// 清空集合
public void clear()

// 判断集合是否包含指定元素
public boolean contains(Object o)
在这里插入图片描述
在这里插入图片描述

应用场景案例

HashSet 类在实际开发中具有广泛的应用场景。下面是一些常见的场景。

去除重复元素

HashSet 类中的元素是唯一的,因此可以用于去除 List 中的重复元素。

代码语言:java
复制
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 2, 3, 4, 5, 4, 5));
Set<Integer> set = new HashSet<>(list);
list.clear();
list.addAll(set);
System.out.println(list); // [1, 2, 3, 4, 5]

判断集合是否包含指定元素

在 HashSet 中,可以使用 contains 方法来判断集合是否包含指定元素。

代码语言:java
复制
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
System.out.println(set.contains(3)); // true
System.out.println(set.contains(6)); // false

去除空元素

HashSet 类中可以存储空元素,因此可以用于去除 List 中的空元素。

代码语言:java
复制
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "", "c", ""));
Set<String> set = new HashSet<>(list);
set.remove("");
list.clear();
list.addAll(set);
System.out.println(list); // [a, b, c]

优缺点分析

优点

  • 可以存储不同类型的数据。
  • 元素是无序的。
  • 可以存储空元素。
  • 具有去重功能。

缺点

  • 查找元素的速度较慢。
  • 当元素较多时,可能会消耗较大的内存空间。

类代码方法介绍

除了上述常用方法之外,HashSet 类还有一些常见的方法。

代码语言:java
复制
// 返回集合中的所有元素
public Iterator<E> iterator()

// 将集合转换为数组
public <T> T[] toArray(T[] a)

// 返回集合的哈希码
public int hashCode()

// 比较两个集合是否相等
public boolean equals(Object o)

// 返回集合的字符串表示形式
public String toString()

// 添加元素
public boolean addAll(Collection<? extends E> c)

// 移除所有元素
public boolean removeAll(Collection<?> c)

// 保留集合中与指定集合的交集
public boolean retainAll(Collection<?> c)

// 判断集合是否包含指定集合中的所有元素
public boolean containsAll(Collection<?> c)

// 将集合转换为流
public Stream<E> stream()

// 将集合转换为并行流
public Stream<E> parallelStream()

拓展:

这是Java集合框架中Collection接口中的一些常用方法,分别实现了以下功能:

  1. iterator():返回集合中的所有元素的迭代器。
  2. toArray(T[] a):将集合转换为指定类型的数组。
  3. hashCode():返回集合的哈希码。
  4. equals(Object o):比较两个集合是否相等。
  5. toString():返回集合的字符串表示形式。
  6. addAll(Collection<? extends E> c):向集合中添加指定集合中的所有元素。
  7. removeAll(Collection<?> c):移除集合中与指定集合相同的元素。
  8. retainAll(Collection<?> c):移除集合中与指定集合不同的元素,保留与指定集合相同的元素。
  9. containsAll(Collection<?> c):判断集合是否包含指定集合中的所有元素。
  10. stream():将集合转换为流。
  11. parallelStream():将集合转换为并行流。

这些方法可以方便地对Java集合进行操作和处理。

测试用例

下面是一些针对 HashSet 类的测试用例。

测试代码演示

代码语言:java
复制
package com.example.javase.se.classes;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @Author ms
 * @Date 2023-11-02 22:36
 */
public class HashSetTest {

    public static void main(String[] args) {
        Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
        System.out.println("set1 size: " + set1.size());

        Set<Integer> set2 = new HashSet<>(Arrays.asList(1, 2, 3));
        System.out.println("set2 add(4): " + set2.add(4));
        System.out.println("set2 add(3): " + set2.add(3));

        Set<Integer> set3 = new HashSet<>(Arrays.asList(1, 2, 3));
        System.out.println("set3 remove(1): " + set3.remove(1));
        System.out.println("set3 remove(4): " + set3.remove(4));

        Set<Integer> set4 = new HashSet<>(Arrays.asList(1, 2, 3));
        System.out.println("set4 contains(2): " + set4.contains(2));
        System.out.println("set4 contains(4): " + set4.contains(4));

        Set<Integer> set5 = new HashSet<>(Arrays.asList(1, 2, 3));
        set5.clear();
        System.out.println("set5 isEmpty: " + set5.isEmpty());
    }
}

测试结果

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

在这里插入图片描述
在这里插入图片描述

测试代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。

这是一个测试 HashSet 的程序,具体分析如下:

  1. 创建 HashSet 对象 set1,并添加元素 1、2、3、4、5,输出 set1 的大小。
  2. 创建 HashSet 对象 set2,并添加元素 1、2、3,尝试添加元素 4 和 3,输出添加结果。
  3. 创建 HashSet 对象 set3,并添加元素 1、2、3,尝试移除元素 1 和 4,输出移除结果。
  4. 创建 HashSet 对象 set4,并添加元素 1、2、3,尝试判断元素 2 和 4 是否存在,输出判断结果。
  5. 创建 HashSet 对象 set5,并添加元素 1、2、3,清空 set5,判断 set5 是否为空,输出判断结果。

以上操作都是使用 Set 接口中的方法进行的,具体来说:

  • 使用 HashSet 的构造方法,可以使用 Arrays.asList() 方法将数组转换成集合,从而快速添加元素。
  • add() 方法返回一个布尔值,表示添加元素的结果。当元素已存在时,不会再次添加,并且返回 false。
  • remove() 方法返回一个布尔值,表示移除元素的结果。当元素不存在时,不会进行移除,并且返回 false。
  • contains() 方法返回一个布尔值,表示集合中是否包含指定元素。
  • clear() 方法可以清空集合中的所有元素,使其成为空集合。
  • isEmpty() 方法可以判断集合是否为空,返回一个布尔值。

总体来说,HashSet 是一种基于哈希表实现的集合,具有快速添加、移除、判断元素是否存在的优势,同时不保证元素的顺序。

优点

  • 可以存储不同类型的数据。
  • 元素是无序的。
  • 可以存储空元素。
  • 具有去重功能。

缺点

  • 查找元素的速度较慢。
  • 当元素较多时,可能会消耗较大的内存空间。

小结

HashSet 类是 Java 中的一种集合类,它可用于存储不同类型的数据,元素是无序的,元素的值可以为 null。HashSet 类可以去除重复元素,具有去重功能。HashSet 类的优缺点如下:

总结

HashSet 类在 Java 中是一个非常实用的集合类。它可以用于存储不同类型的数据,并且具有去重功能。在实际开发中,我们可以使用 HashSet 类来去除 List 中的重复元素、判断集合中是否包含指定元素等等。但是需要注意的是,当元素较多时,可能会消耗较大的内存空间,因此在使用 HashSet 类时需要谨慎考虑。

... ...

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

... ...

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!

⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 摘要
  • HashSet类
    • 简介
      • 源代码解析
        • 成员变量
        • 构造方法
        • 类方法
      • 应用场景案例
        • 去除重复元素
        • 判断集合是否包含指定元素
        • 去除空元素
      • 优缺点分析
        • 优点
        • 缺点
      • 类代码方法介绍
        • 测试用例
          • 测试代码演示
          • 测试结果
          • 测试代码分析
          • 优点
          • 缺点
        • 小结
        • 总结
        • 文末
        相关产品与服务
        腾讯云代码分析
        腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档