Java剖析 : HashMap底层存储数据的结构 | HashSet添加不重复元素底层原理

                              HashSet底层剖析

前言:

我们知道Set中所存储的元素是不重复的,那么Set接口的实现类HashSet在添加元素时是怎么避免重复的呢?

★ HashSet在添加元素时,是如何判断元素重复的?        

●  在底层会先调用hashCode(),注意,Object中的hashCode()返回的是对象的地址,此时并不会调用;此时调用的是类中重写的hashCode(),返回的是根据内容计算的哈希值,遍历时,会用哈希值先比较是否相等,会提高比较的效率;但哈希值会存在问题:内容不同,哈希值相同;这种情况下再调equals比较内容,这样既保证效率又确保安全。

案例:

  • 这是错误写法,此时默认调用的是Object类中hashCode( ),返回对象地址
import java.util.HashSet;
import java.util.Objects;

public class Student {
    private String name ;
    private String num;


    public Student(String name, String num) {
        this.name = name;
        this.num = num;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", num='" + num + '\'' +
                '}';
    }
    
        public static void main(String[] args) {
            HashSet<Student> set = new HashSet<>();
            Student s1 = new Student("小王1","10001");
            Student s2 = new Student("小王2","10002");
            Student s3 = new Student("小王3","10003");
            Student s4 = new Student("小王1","10001");
            set.add(s1);
            set.add(s2);
            set.add(s3);
            set.add(s4);
            System.out.println(set);
            
        }
    }
  • 此时之所以出现重复,因为默认调用的是Object类中hashCode( ),返回对象地址,s1和s4内容虽然相同,但作为两个对象,地址肯定不同。

  • 正确写法应该是,在Student类中重写hashCode()和equals()
package Demo;

import java.util.HashSet;
import java.util.Objects;

public class Student {
    private String name ;
    private String num;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return num.equals(student.num);
    }

    @Override
    public int hashCode() {
        return Objects.hash(num);
    }

    public Student(String name, String num) {
        this.name = name;
        this.num = num;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", num='" + num + '\'' +
                '}';
    }

        public static void main(String[] args) {
            HashSet<Student> set = new HashSet<>();
            Student s1 = new Student("小王1","10001");
            Student s2 = new Student("小王2","10002");
            Student s3 = new Student("小王3","10003");
            Student s4 = new Student("小王1","10001");
            set.add(s1);
            set.add(s2);
            set.add(s3);
            set.add(s4);
            System.out.println(set);

        }
    }

  • 这样就能避免重复了(此图是s1,s4重复,但只输出s1)| 注意:HashSet: 元素是无序

补充:

  • 如何快速生成hashCode()和equals()的重写方法?

右键选择Generate,选择equals()and hashCode(),选择重写的属性


                               HashMap底层剖析

HashMap底层存储数据的结构 :(面试高频题)

○ 底层使用了一个长度默认为16的哈希数组,用来确定元素的位置,每次用key计算出哈希值,再     用哈希值%数组长度确定元素位置,将元素放在哈希表中指定的位置。

○ 后来继续添加元素,如果出现位置相同且不重复的元素,那么将后来元素添加到之前元素的next     节点。

○ 当链表长度等于8哈希数组的长度大于64时链表会自动转为红黑树

补充: 哈希表负载因子为0.75 , 当哈希表使用数组的0.75倍时会自动扩容为原来数组长的2倍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/450357.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Android9】cm311-5 zg/yst 2+8 国科6323 已root乐家桌面卡刷包免拆禁休眠适合跑助手

已刷好乐家&#xff0c;无广告&#xff0c;不死系统&#xff0c;目前测试稳定运行&#xff0c;不休眠&#xff0c;无后门 【国科6323&#xff0c;cm311-5s等型号理论通刷&#xff0c;未全部测试】 1、已root&#xff0c;安卓9&#xff0c;通刷包&#xff0c;免拆卡刷包&#xf…

H12-811_19

19.(多选题)如下图所示的网络&#xff0c;下列哪些命令可以使RouterA可以转发目的IP地址为10.0.3.3的效据包? A.ip route-static 10.0.3.3 255.255.255.255 10.0.12.2 B.ip route-static 10.0.2.2 255.255.255.255 10.0.12.2 ip route-static 10.0.3.3 255.255.255.255 10.0…

基于eleiment-plus的表格select控件

控件不是我写的&#xff0c;来源于scui,但在使用中遇到了一些问题&#xff0c;希望能把过程记录下来&#xff0c;同时把这个问题修复掉。 在使用的时候对控件进行二级封装&#xff0c;比如我的一个商品组件&#xff0c;再很多地方可以用到&#xff0c;于是 <template>&l…

让人头疼的AbstractQueuedSynchronizer究竟是什么?

AQS 但凡了解多线程的对于AQS应该都有所耳闻吧(我第一次知道AQS还是在一次面试中&#xff0c;那次被虐的老惨了)&#xff0c;AQS即AbstractQueuedSynchronizer队列同步器&#xff0c;是一个抽象类&#xff0c;它是从java5开始的同步组件的基础框架&#xff0c;它仅仅只是定义了…

第二十一天-NumPy

目录 什么是NumPy NumPy使用 1.数组的创建 2.类型转换 3.赠删改查 4.数组运算 5.矩阵运算 什么是NumPy 1.NumPy操作的是多维数组&#xff0c;什么是纬度&#xff1f; NumPy使用 1. 安装 pip install numpy import numpy as np 2.官网&#xff1a; 中文官网&#xff1a…

腾轩科技传媒讲解百度百科词条品牌怎么创建?

品牌百度百科是为企业或个人创建的一个专门展示品牌信息、活动、产品等内容的百度百科页面。通过品牌百度百科&#xff0c;企业可以向用户展示其核心价值、产品特色&#xff0c;提升品牌知名度&#xff0c;并在互联网上建立一个权威的品牌形象。本文腾轩科技传媒讲解百度百科词…

MySQL分析sql语句的性能瓶颈的几种方式介绍

在 MySQL 中&#xff0c;性能瓶颈可能会导致数据库系统运行缓慢&#xff0c;影响用户体验。为了确保数据库的性能&#xff0c;识别和解决性能瓶颈是非常重要的。以下是一些常用的方法来分析 SQL 语句的性能瓶颈&#xff1a; 1. EXPLAIN 语句 EXPLAIN 是一个强大的工具&#xff…

意大利数据监管机构对Sora展开调查

意大利数据保护监管机构 Garante3月8日宣布&#xff0c;将对 OpenAI 新推出的视频人工智能模型 Sora 展开隐私调查。 监管机构虽然没有对 OpenAI 提出任何具体指控&#xff0c;但表示正在研究 Sora 对意大利&#xff08;包括欧盟&#xff09;个人数据使用可能产生的潜在影响&am…

归并排序 刷题笔记

归并排序的写法 归并排序 分治双指针 1.定义一个mid if(l>r)return ; 2.分治 sort(q,l,mid); sort(q,mid1,r); 3. 双指针 int il,jmid,k0; 将双序列扫入 缓存数组 条件 while(i<mid&&j<r) 两个数列比较大小 小的一方 进入缓存数组 4. 扫尾 while(…

Neo4j 批量导入数据 从官方文档学习LOAD CSV 命令 小白可食用版

学习LOAD CSV&#x1f680; 在使用Neo4j进行大量数据导入的时候&#xff0c;发现如果用代码自动一行一行的导入效率过低&#xff0c;因此明白了为什么需要用到批量导入功能&#xff0c;在Neo4j中允许批量导入CSV文件格式&#xff0c;刚开始从网上的中看了各种半残的博客或者视频…

基于PyTorch深度学习实战入门系列-(3)Numpy基础下

使用mat创建矩阵 a np.mat([[5, 6], [7, 8]]) b np.mat([[1, 2], [3, 4]]) print(a) print(b) print(type(a)) print(type(b))矩阵的加减乘除运算 data1 np.mat([[1, 2], [3, 4], [5, 6]]) data2 np.mat([1, 2]) data3 np.mat([[5, 6], [7, 8]]) print(data1 data2) prin…

MySQL中的事务

MySQL中的事务 简介操作方式一方式二 事务四大特性(ACID)并发事务问题事务的隔离级别 简介 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xf…

一文读懂:代码签名证书详解

背景&#xff1a;代码签名证书是使得软件开发商能对其软件代码进行数字签名&#xff0c;从而让该证书为软件开发商提供了一个理想的安全环境&#xff0c;也同样对其软件代码进行数字签名。 原理是通过对代码的数字签名来标识软件来源以及软件开发者的真实身份&#xff0c;保证…

SQL 多表查询

文章目录 多表查询的分类等值连接非等值连接自连接非自连接内连接外连接左外连接右外连接满外连接 SQL连接 JOINSQL99 语法新特性 自然连接 NATURAL JOIN & USING 多表查询的分类 等值连接 VS 非等值连接自连接 VS 非自连接内连接 VS 外连接 等值连接 关联的表有连接字段…

ThreadLocal是什么,ThreadLocal源码分析,ThreadLocal应用,ThreadLocal内存泄漏

ThreadLocal是什么&#xff0c;ThreadLocal源码分析&#xff0c;ThreadLocal应用&#xff0c;ThreadLocal内存泄漏 目录 本文导读 一、ThreadLocal概述 二、ThreadLocal源码解析 三、ThreadLocal在多线程并发中的应用 四、ThreadLocal与内存泄漏问题 总结 博主v&#xf…

MATLAB 四点确定唯一球面参数(44)

MATLAB 四点确定唯一球面参数(44) 一、算法简介二、算法实现1.代码2.结果一、算法简介 根据给定的四个点,快速拟合获取球的中心和半径,具体代码如下: 二、算法实现 1.代码 代码如下(示例): point1 = [0.0, 0.0, 0.0]

Matlab进阶绘图第43期—双三角曲面图

在《Matlab论文插图绘制模板第68期—三角曲面图(Trisurf)》中&#xff0c;我分享过三角曲面图的绘制模板。 然而&#xff0c;有的时候&#xff0c;需要在一张图上绘制两个及以上的三角曲面图&#xff0c;且每个三角曲面图使用不同的配色方案。 在Matlab中&#xff0c;一张图上…

python 基础知识点(蓝桥杯python科目个人复习计划62)

今日复习内容&#xff1a;做题 例题1&#xff1a;付账问题 问题描述&#xff1a; 几个人一起出去吃饭是常有的事&#xff0c;但在结账的时候&#xff0c;常常会出现一些争执。 现在有n个人出去吃饭&#xff0c;他们总共消费了S元&#xff0c;其中第i人带了ai元。幸运的是&a…

【Vue】.sync 修饰符作用

文章目录 基本用法 基本用法 官方文档是这样介绍的&#xff1a;.sync 修饰符 简单来说就是实现父子组件数据之间的双向绑定&#xff0c;当子组件修改了一个 props 的值时&#xff0c;也会同步到父组件中&#xff0c;实现子组件同步修改父组件&#xff0c;与v-model类似。类别在…

【Python】新手入门学习:什么是相对路径?

【Python】新手入门学习&#xff1a;什么是相对路径&#xff1f; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得…