equal和hashcode
- equal和hashcode
- 核心代码示例
- hashCode() 方法
- 哈希码
- 哈希码原理
- equals()与hashcode()的联系
- 图形展示
- 完整的示例代码
核心代码示例
public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) {return false;}Brand brand = (Brand) o;return Objects.equals(name, brand.name);}@Overridepublic int hashCode() {return Objects.hash(name);}
hashCode() 方法
- hashCode() 的作用是为对象生成一个数字“指纹”(哈希码),这个“指纹”主要用于提高在基于哈希的集合(如 HashSet、HashMap)中的查找速度.
哈希码
哈希码是一个 int 类型的整数。理想情况下,相等的对象应该拥有相同的哈希码。不相等的对象,它们的哈希码最好也不同(但这不是强制要求,只是为了让性能更好)。
哈希码原理
- 计算哈希码: 当你要添加一个新对象(比如 new Brand("BMW"))时,HashSet 首先调用这个对象的 hashCode() 方法,得到一个数字,比如 123。
- 定位“桶”: HashSet 内部其实是一个数组,它用这个哈希码(123)通过一个算法计算出这个对象应该存放在数组的哪个位置(这个位置被称为“桶”或“bucket”)。
快速判断: - 比较: 如果这个“桶”是空的,说明这个对象肯定不存在,直接放进去。整个过程连一次 equals() 调用都不需要;如果这个“桶”里已经有对象了(这种情况叫“哈希冲突”),这时才需要启动 equals() 方法,让新对象和桶里的那几个对象逐一比较,看是否真的相等。
equals()与hashcode()的联系
- Java 规定,这两个方法必须遵守一个非常重要的契约:
如果两个对象通过 equals() 方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode() 方法都必须产生相同的整数结果。
反过来则不成立:如果两个对象的 hashCode() 相同,它们不一定 equals()(这就是哈希冲突)。
所以在修改判断标准时,equals和hashcode要共同重写。
图形展示
完整的示例代码
点击查看代码
import java.util.*;
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String line = scanner.nextLine();int n = Integer.parseInt(line);List<Car> cars = new ArrayList<>();List<Brand> brands = new ArrayList<>();for(int i=0;i<n;i++) {line = scanner.nextLine();Brand brand = new Brand(line);if(!brands.contains(brand)) {//应用brands.add(brand);cars.add(new Car(brand));}else {System.out.println(line+" exists");}}for(Car car:cars) {System.out.println(car);}System.out.println(ArrayList.class.getClassLoader());scanner.close();}
}
class Brand{private String name;public Brand(String name) {this.name = name;}public String toString() {return "Brand [name="+name+"]";}public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) //判断相同类{return false;}Brand brand = (Brand) o;return Objects.equals(name, brand.name);}@Overridepublic int hashCode() {return Objects.hash(name);}
}
class Car{int id;Brand brand;private static int counter=0;static {System.out.println("0 car");}public Car(Brand brand) {this.brand = brand;this.id = ++counter;}public String toString() {return "Car [id="+id+"brand="+brand.toString()+"]";}
}