java中哈希家族底层原理

HashSet如何判断两个对象是否相等?

在Java中,HashSet是使用哈希表实现的,其核心是通过对象的哈希码来快速查找和判断元素是否存在。在判断两个对象是否相等时,HashSet并不直接比较对象的内容,而是通过比较它们的哈希码来快速做出决策。

在Java中,对象相等性的判断有两个条件:

  1. 两个对象引用指向同一个对象(即他们是同一个对象)。
  2. 两个对象引用指向不同的对象,但这两个对象的内容相等。

对于第一个条件,可以通过比较两个引用是否完全相同(即使用“==”操作符)来判断。而对于第二个条件,则需要通过实现equals()方法来定义如何判断两个对象的内容是否相等。

当我们在HashSet中添加或查找元素时,HashSet首先会计算对象的哈希码,然后使用这个哈希码来决定将对象存储在哈希表的哪个位置。然后,如果我们需要查找一个元素,HashSet会计算这个元素的哈希码,并查看该位置的元素是否与我们要查找的元素相等。这个“相等”的判断也是通过equals()方法来实现的。

所以,对于HashSet来说,它并不直接比较对象的每一个属性是否都相同,而是通过比较对象的哈希码来快速判断两个对象是否可能相等。如果两个对象的哈希码不同,那么它们肯定不相等;如果两个对象的哈希码相同,HashSet才会进一步调用equals()方法来最终确定它们是否相等。

请注意,如果你想在HashSet中使用自定义对象,并且这些对象需要根据某些特定属性来判断相等性(例如,你想把表示同一个人的两个不同的实例视为相等的),那么你需要确保你的自定义类正确地覆盖了equals()hashCode()方法。

HashMap的底层实现是什么?

HashMap 是 Java 集合框架中的一种数据结构,它使用哈希表(Hash Table)作为其底层实现。哈希表是一种数据结构,它通过将键(key)映射到桶(bucket)中来存储数据。

在 HashMap 中,每个键值对(key-value pair)都存储在一个节点(Node)中,该节点包含键、值和指向下一个节点的指针。HashMap 使用哈希函数将键映射到桶的索引,这样就可以快速定位到特定的键值对。

HashMap 的底层实现主要包括以下几个方面:

  1. 数组和链表:HashMap 使用一个数组来存储桶,每个桶中包含一个链表,链表中的节点存储了键值对。当发生哈希冲突时,即两个键的哈希值相同,它们会被存储在同一个桶中的链表中。
  2. 哈希函数:HashMap 使用一个哈希函数来将键映射到桶的索引。默认情况下,HashMap 使用对象的 hashCode() 方法来计算哈希值。
  3. 扩容和缩容:当 HashMap 中的元素数量过多或过少时,会进行扩容或缩容操作。扩容是指增加桶的数量,缩容是指减少桶的数量。
  4. 重新哈希:当发生哈希冲突时,HashMap 会使用链表来存储冲突的键值对。当链表过长时,会进行重新哈希操作,即改变哈希函数,使得更多的键能够映射到不同的桶中,从而减少冲突。

总之,HashMap 的底层实现主要包括数组、链表、哈希函数、扩容、缩容和重新哈希等机制。这些机制共同协作,使得 HashMap 能够在常数时间内完成插入、删除和查找操作。

Hashtable和ConcurrentHashMap之间有什么区别?

Hashtable和ConcurrentHashMap是Java中的两种常用的线程安全的Map数据结构,它们之间存在以下主要差异:

  1. 线程安全性:两者都提供了线程安全,但ConcurrentHashMap的线程安全性更强。在Hashtable中,当多个线程同时访问时,需要同步处理,这可能导致性能下降。而ConcurrentHashMap使用了更细粒度的锁,使得在多线程环境下提供了更好的性能和可靠性。
  2. 锁的粒度:在Hashtable中,整个表是加锁的,这可能导致锁竞争激烈,降低并发性能。而ConcurrentHashMap则是将整个哈希表划分为多个小的段(Segment),每个段包含了若干个键值对(Entry)。当多个线程同时访问哈希表时,它们可以同时访问不同的段,从而避免了锁竞争,大大提高了并发度和性能。
  3. 扩容策略:在Hashtable中,一旦触发扩容操作,就需要持有锁的线程完成整个扩容过程。这个过程涉及到大量的元素拷贝,效率较低。而ConcurrentHashMap的扩容操作则是化整为零,扩容时新旧空间同时存在。后续的线程也会执行上述操作,直到将所有元素全部搬运完毕。由于每次只需要拷贝少量元素,效率较高。
  4. 计算hash值方式:在Hashtable中,通过计算key的hashCode()来得到hash值,这个值就是最终的hash值。而在ConcurrentHashMap中,当出现hash冲突时,会通过链表+红黑树的方式解决。此外,ConcurrentHashMap还有一个hash方法重新计算了key的hash值,因为hash冲突变高,所以通过一种方法重算hash值的方法:这里计算hash值,先调用hashCode方法计算出来一个hash值,再将hash与右移16位后相异或,从而得到新的hash值。
  5. 性能:ConcurrentHashMap在很多方面都优于Hashtable。例如,ConcurrentHashMap的size属性通过CAS更新(较快),而Hashtable的size属性通过synchronized操作更新(较慢)。

综上所述,与Hashtable相比,ConcurrentHashMap提供了更高的并发性和更好的性能。在大多数情况下,应该优先选择ConcurrentHashMap作为线程安全的Map实现。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01_前端框架之Bootstrap的应用

day01_前端框架之Bootstrap的应用 本课目标 能够完成 Bootstrap 环境搭建能够理解 Bootstrap 的栅格布局能够根据 Bootstrap 相关文档使用Bootstrap组件能够根据 Bootstrap 重构主页和表单页 第1章 bootstrap简介 1.1 什么是bootstrap Bootstrap 是全球最受欢迎的前端组件库…

ES模糊查询不区分大写

一、 概述 最近接到新任务,产品说名称能支持模糊搜索,且不区分大小写。 以为是数据库操作,那岂不是easy,分分钟的事情,往往事情觉得简单的时候就不简单了,脑子忽然闪现想起该模块数据是放在ES里的&#xf…

C++中特殊类的设计与单例模式的简易实现

设计一个只能在堆上创建对象的类 对于这种特殊类的设计我们一般都是优先考虑私有构造函数。然后对于一些特殊要求就直接通过静态成员函数的实现来完成。 class A//构造函数私有(也可以析构函数私有) { public:static A* creat(){return new A;} privat…

docker容器下php框架laravel的使用问题与解决方案

DB_CONNECTIONmysqlDB_HOSTlocalhost DB_CONNECTIONmysqlDB_HOSTdocker33-mysql-1 容器中只有数据库结构 进入MySQL容器内,创建表结构,添加数据 代码层面需要转换成数组 $query->get([*])->toArray(); 分页数据框架会返回带有data的数据&#xf…

计算机网络-AAA原理概述

对于任何网络,用户管理都是最基本的安全管理要求之一,在华为设备管理中通过AAA框架进行认证、授权、计费实现安全验证。 一、AAA概述 AAA(Authentication(认证), Authorization(授权), and Accounting(计费))是一种管理框架&#…

大模型微调实战笔记

大模型三要素 1.算法:模型结构,训练方法 2.数据:数据和模型效果之间的关系,token分词方法 3.算力:英伟达GPU,模型量化 基于大模型对话的系统架构 基于Lora的模型训练最好用,成本低好上手 提…

CentOS 7安装全解析:适合初学者的指导

目录 前言 一.centos安装 1.下载镜像文件 2.安装 二.远程连接,换源 1.下载并且使用MobaXtermMobaXterm free Xserver and tabbed SSH client for Windows (mobatek.net)https://mobaxterm.mobatek.net/ 远程连接 2.换源 前言 在当今的信息化时代&#xff0c…

【Leetcode 965.】判断单值二叉树

单值二叉树: 示例一: 示例二: 代码: bool isUnivalTree(struct TreeNode* root) {if(rootNULL)return true;if(root->left&&root->left->val!root->val)return false;if(root->right&&root-&…

leetcode-相交链表

160. 相交链表 注:两个链表相交不是指两个节点的值相等,而是指节点所在的地址 # Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val x # self.next Noneclass Solution:def getInters…

【LeetCode-135】分发糖果(贪心)

LeetCode135.分发糖果 题目描述 老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分。 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果。…

Neos的渗透测试靶机练习——DarkHole-2

DarkHole-2 一、实验环境二、开始渗透1. 搜集信息2. git文件泄露3. SQL注入4. 提权 三、总结 一、实验环境 虚拟机软件:VirtualBox 攻击机:kali linux(网卡初始为仅主机模式,要有安全意识) 靶机:DarkHole-…

vue3+Element plus实现登录功能

一、想要实现的效果 二、搭建登录静态 1、实现左边背景和右边登录栏的总体布局布局&#xff1a; <el-row class"content"><!--el-col 列&#xff1a; --><el-col :span"16" :xs"0" class"content-left"></el-c…

仓储管理系统——软件工程报告(可行性研究报告及分析)①

可行性研究报告及分析 一、问题定义 1.1项目背景 随着社会的发展以及企业规模的扩大和业务的复杂化&#xff0c;仓库管理变得愈发重要。传统的手工管理方式已经导致了一系列问题&#xff0c;包括库存准确性低、订单处理效率慢等。为了提高仓库运作效率、降低成本并优化库存管…

Qt —— QCharts之曲线示波器(附源码)

示例效果 介绍 Qt5.7 版本后 Qt Charts 的发布。Qt Charts可以创建时尚的、交互式的、以数据为中心的用户界面。Qt Charts使用Qt Charts来简化集成。图表组件可以用作或对象或QML类型。 该类管理不同类型的系列和其他图表相关对象(如图例和轴)的图形表示形式。是一个可以在 .…

unity 单例模式(实例详解)

文章目录 在Unity中&#xff0c;单例模式是一种常用的编程设计模式&#xff0c;用于确保在整个应用程序生命周期中&#xff0c;只有一个类的实例存在。这样可以保证数据的全局唯一性和共享性&#xff0c;例如游戏场景中的资源管理器、游戏控制器、事件管理器等。 以下是一个简单…

如何用 500 行 SQL 实现 GPT2学习

目录 理论背景实现过程GenerationTokenizerEmbeddingsAttention为什么我们需要有因果掩码&#xff1f;为什么矩阵是 Q&#xff0c;K 和 V&#xff1f; BlocksTokens为什么要使用 softmax 转换概率&#xff1f;Inference 俄罗斯有个大佬每年都会用 SQL 来实现一个挑战庆祝新年&a…

Android:JNI实战,理论详解、Java与Jni数据调用

一.概述 上一篇博文讲解了如何搭建一个可以加载和链接第三方库、编译C/C文件的Jni Demo App。 这篇博文在这个Jni Demo App的基础上&#xff0c;从实战出发详细讲解 Jni 开发语法。 接下来&#xff0c;先用一小节将Jni开发比较重要的理论知识点过一下&#xff0c;然后进行代…

matlab appdesigner系列-常用17-编辑字段(数值、文本)

编辑字段&#xff08;数值、文本&#xff09;可直接键入数值、文本&#xff0c;其他组件直接调用其值。也可以利用把其他组件回调的值&#xff0c;返回到编辑字段&#xff08;数值、文本&#xff09;进行显示。 示例&#xff1a;利用按钮组件改变编辑字段&#xff08;数值&…

详解APQC流程分级分类框架PCF13个高阶分类和5级业务流程

一&#xff1a;什么是APQC 美国生产力与质量中心(American Productivity and Quality Center&#xff0c;简称为APQC)&#xff0c;创立于1977年是一个会员制的非营利机构&#xff0c;使命是“发现有效的改进方法&#xff0c;广泛地传播其发现成果&#xff0c;实现个人之间及其…

NLP自然语言处理原理应用讲解

自然语言处理&#xff08;NLP&#xff09;是人工智能领域中研究如何让计算机理解和处理人类自然语言的一门学科。它的应用广泛&#xff0c;例如在搜索引擎、聊天机器人、机器翻译等领域中都发挥了重要的作用。 NLP的基本原理是通过对大量的语料库进行训练&#xff0c;让计算机…