哈希碰撞是指两个不同的输入数据在经过哈希函数运算后产生相同的哈希值。哈希函数通常将输入数据映射到一个较小的范围,比如一个固定大小的哈希码空间,但输入数据的范围可能远远大于哈希码空间。因此,多个不同的输入可能映射到相同的哈希码,这就是哈希碰撞的发生。
哈希碰撞可能发生在任何使用哈希函数的场景,包括哈希表、哈希集合、哈希集映射等。在这些数据结构中,哈希函数用于将键(key)映射到索引或位置,以便快速查找或检索数据。
解决哈希碰撞的一些常见方法包括:
-
开放寻址法(Open Addressing): 当发生碰撞时,继续探查哈希表中的下一个位置,直到找到一个空槽或者满足特定条件的槽。
-
链地址法(Chaining): 每个哈希桶存储一个链表或其他数据结构,所有哈希到同一桶的元素都存储在链表中。
-
再哈希(Rehashing): 当哈希表的负载因子达到一定阈值时,对哈希表进行扩容,重新计算哈希码并重新分配元素,以减少碰撞的可能性。
-
良好设计的哈希函数: 使用高质量、均匀分布的哈希函数可以减少碰撞的发生。
哈希碰撞是不可避免
点击查看代码
package com.itheima.javase;
import java.util.Objects;
class Student{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class HashCode {
/**
* 哈希值 就是一个int类型的数值,Java中每个对象都有一个哈希值。
*
* Java中的所有对象,都可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值。
*
* 对象哈希值的特点
*
* 同一个对象多次调用hashCode()方法返回的哈希值是相同的。
*
* 不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞)。
*
* @param args
*/
public static void main(String[] args) {
Student s1 = new Student("张三", 25);
Student s2 = new Student("张三", 25);
Student s3 = new Student("李四", 25);
System.out.println("s1.hashCode() = "+s1.hashCode());//s1.hashCode() = 24022545
System.out.println("s2.hashCode() = "+s2.hashCode());//s2.hashCode() = 24022545
System.out.println("s3.hashCode() = "+s2.hashCode());//s3.hashCode() = 24022545
System.out.println(s1.hashCode() == s2.hashCode());// true
System.out.println(s1.hashCode() == s3.hashCode());// false
}
}