Hash碰撞

news/2024/11/9 5:06:10/

Hash碰撞

什么是Hash碰撞

Hash碰撞是指两个不同的输入值,经过哈希函数的处理后,得到相同的输出值,这种情况被称之为哈希碰撞。

  • 例如:两个不同的对象(object1和object2的值)经过Hash函数计算后的,得到的hash值相同,object2应放到object1的位置,但是存储桶中的位置已经被object1占用了,导致冲突

哈希函数是

为什么会发生Hash碰撞

哈希表是一种数据结构,它使用哈希函数将键映射到存储桶中。哈希函数将键转换为索引,这个索引指向哈希表中的一个桶。哈希表的目的是提供一种快速的查找方法,它可以在较快的时间内查找一个键。

当然,这需要一个好的哈希函数,它可以将键均匀地分布在哈希表中。如果哈希函数不好,就会出现哈希碰撞,这会导致性能下降。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fULBcw7u-1683776857310)(E:\Java笔记\Java优化\Hash\Hash碰撞\Hash碰撞.assets\image-20230511110034878.png)]

解决Hash碰撞

在这种情况下,我们可以使用链式哈希表来解决哈希碰撞的问题。链式哈希表是一种将哈希值相同的元素存储在同一个链表中的哈希表。当发生哈希碰撞时,我们只需要将新元素添加到对应的链表中即可。这样可以保证哈希表的性能和正确性。

package com.sin.demo;import java.util.LinkedList;/*** @CreateName SIN* @CreateDate 2023/05/11 11:04* @description 链式哈希表,用来解决hash碰撞的问题。*              具体实现:将hash值相同的元素存储在同一个链表中,当发生hash碰撞时,*                      只需要将新的元素添加到对应的链表中即可,这样可以保证hash表的新能和正确性*/
public class ChainedHashTable<K, V> {//声明一个链表数组private LinkedList<Entry<K, V>>[] table;//记录长度private int size;/*** 构造方法* @param capacity 传入hash表容量*/public ChainedHashTable(int capacity) {//初始化链表数组长度table = new LinkedList[capacity];//初始长度为0size = 0;}/*** 添加元素* @param key 键* @param value 值*/public void put(K key, V value) {//计算哈希值int index = hash(key);//如果当前索引位置为nullif (table[index] == null) {//创建一个新的链表在当前索引table[index] = new LinkedList<>();}// 遍历当前索引的链表for (Entry<K, V> entry : table[index]) {//判断链表中是否有这个key键,if (entry.getKey().equals(key)) {//如果有则更新对应的value值entry.setValue(value);//直接返回return;}}//如果不存在将新的元素(键值对)添加到链表中table[index].add(new Entry<>(key, value));//增加长度size++;}/*** 获取元素* @param key 键* @return 返回对应的值*/public V get(K key) {//计算hash值int index = hash(key);//如果当前值为nullif (table[index] == null) {//返回nullreturn null;}//遍历该位置的链表for (Entry<K, V> entry : table[index]) {//判断链表中是否有这个key键,if (entry.getKey().equals(key)) {//存在则返回元素的值return entry.getValue();}}//否则返回nullreturn null;}/*** 删除元素* @param key 所需要删除的key* @return false:删除失败,true:删除成功*/public boolean remove(K key) {//计算hash值int index = hash(key);//如果当前位置为nullif (table[index] == null) {//返回falsereturn false;}//遍历该位置的链表for (Entry<K, V> entry : table[index]) {//判断链表中是否有这个key键,if (entry.getKey().equals(key)) {//从链表中删除该元素table[index].remove(entry);//减小长度size--;//返回truereturn true;}}//返回falsereturn false;}/*** 获取长度* @return 返回长度*/public int size() {return size;}/*** 计算hash值* @param key 键* @return 返回自定义的hash值(可按照自己的规则编写)*/private int hash(K key) {//绝对值并取模return Math.abs(key.hashCode()) % table.length;}/*** 静态内部类* @param <K>* @param <V>*/private static class Entry<K, V> {//key,键private K key;//value,值private V value;/*** 构造方法* @param key 传入的key* @param value 传入的值*/public Entry(K key, V value) {//初始化键和值this.key = key;this.value = value;}// 获取键public K getKey() {// 返回键return key;}// 获取值public V getValue() {// 返回值return value;}// 设置值public void setValue(V value) {// 更新值this.value = value;}}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XdBDF8ea-1683776857311)(E:\Java笔记\Java优化\Hash\Hash碰撞\Hash碰撞.assets\image-20230511113659169.png)]

解析:

方法返回值说明
ChainedHashTable构造方法,创建对象时需要传入具体的长度
putvoid添加元素,先计算key的hash值,判断是否有这个key,没有新建一个l链表并添加到数组元素的末尾。有则更新对应的value
getV获取元素,先计算key的hash值,判断是否有这个key,没有则返回null,然后遍历链表,有则返回对应的value,没有返回null
removeboolean删除元素,先计算key的hash值,判断是否有这个key,没有则返回false,然后遍历链表,有则删除对应的value,没有返回false
sizeint获取长度
hashint计算hash值

代码持续开发中:不合理之处,可指导指导!!!

img


http://www.ppmy.cn/news/67880.html

相关文章

unity打造路径编辑与导航系统

Unity是一款非常流行的游戏引擎&#xff0c;它提供了丰富的工具和API&#xff0c;方便开发者快速创建游戏。其中&#xff0c;路径编辑与导航系统是游戏开发中非常重要的一部分&#xff0c;可以帮助玩家更好地探索游戏世界&#xff0c;提升游戏体验。本文将详细介绍如何在Unity中…

阿里云争食币圈

阿里云的触手正在向币圈延伸。几天前&#xff0c;阿里云与Avalanche区块链和MUA DAO联合推出Cloudverse&#xff0c;为想要在链上部署元宇宙的企业提供一站式解决方案。 Avalanche是典型的币圈项目&#xff0c;链上的一切价值流转都以加密货币结算。此次合作释放出阿里云在Web…

设计模式-策略模式

策略模式 文章目录 策略模式什么是策略模式为什么要用策略模式如何使用策略模式1、策略的定义2、策略的创建3、策略的使用 如何优化有状态的策略模式总结 什么是策略模式 定义一族算法类&#xff0c;将每个算法分别封装起来&#xff0c;让它们可以互相替换。策略模式可以使算法…

【C语言】手把手教你文件操作

文章目录 一、前言二、文件的打开和关闭1. fopen函数2. fclose函数 三、文件的顺序读写四、文件的随机读写1. fseek函数2. ftell函数3. fwind函数 一、前言 程序运行时&#xff0c;数据存放在内存中&#xff0c;而当程序退出后&#xff0c;数据也就不复存在。 想做到数据持久化…

发现一个国产BI软件,做财务数据分析效果绝了

如果是一般的财务数据分析&#xff0c;BI软件们都能做&#xff0c;但如果真要深入了解财务痛点&#xff0c;逐个击破财务数据分析难点&#xff0c;实现多维立体自助式的财务数据分析&#xff0c;那就难。就目前而言&#xff0c;财务数据分析做得好的国产BI软件也就一个奥威BI软…

Flask小知识点

1、Flask 组成&#xff1a;werkzueg(专门用来处理请求相关URL) jinja2(用来渲染模板页面) 其他扩展包(flask-cache) 2、自定义转换器 #重写父类BaseConverter class MyRegexConverter(BaseConverter):# regex \d{3}def __init__(self, map, regex):super(MyRegexConverte…

SM2 椭圆曲线公钥密码算法(附源码分析)

一、前言 Koblitz与Miller分别于1985年各自独立地将椭圆曲线应用于公钥密码系统。椭圆曲线有如下性质: 有限域上椭圆曲线在点加运算下构成有限交换群,且阶与基域规模相近;类似于有限域乘法群的乘幂运算,椭圆曲线多倍点运算构成一个单向函数。本文要介绍的SM2算法即为一种椭…

测试自动化工具_Katalon

测试自动化_Katalon 1.概述 ​ Katalon界面的自动化测试工具&#xff0c;简称KS&#xff0c;于2015年推出。是开源的&#xff0c;提供的版本有免费的版本&#xff0c;还有企业版是收费的。如下图。其中的服务台功能应该是持续继承的支持。可试用一个月。 ​ 最初是支持Web UI…