equals方法 和 hashCode方法
来源:互联网 发布:@Requestbody解析json 编辑:程序博客网 时间:2024/05/21 21:48
Object 类有equals方法和hashCode方法, 定义如下:
boolean java.lang.Object.equals(Object obj) //注意参数变量类型是Object.
public native int hashCode();
对象等同,通常指==相等。
如果对象存在“逻辑相等”,而且超类没有重写(override) equals方法以实现逻辑相等,则需要重写equals方法和hashCode方法。
Java Object 规范要求, 如果重写了equals方法,必须同时重写hashCode方法,否则可能无法查询到存储在散列集合中的对象。
两个对象equals相等,那么hashCode一定相同,反之则不成立。
如何重写equals方法和hashCode方法呢?
重写equals方法:
1. 使用==操作符检查 “参数是否为这个对象的引用”;
2. 使用instanceof检查“参数是否是正确的类型”;
3. 把参数转换成正确的类型;
4. “关键”域比较
示例: 员工类Employee 有多个域,存在这样的“逻辑相等”:
如果两个Employee 对象的“关键”域employeeId和name都相同,则这两个Employee对象相同。
public class Employee { private int employeeId; private String name; private Date onboardDate; private String title; public Employee(int employeeId, String name) { this.employeeId = employeeId; this.name = name; } public int getEmployeeId() { return employeeId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getOnboardDate() { return onboardDate; } public void setOnboardDate(Date onboardDate) { this.onboardDate = onboardDate; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @Override public boolean equals(Object obj) { if(this == obj) return true; if(!(obj instanceof Employee)) return false; Employee employee = (Employee)obj; return this.employeeId == employee.employeeId && (this.name == employee.name || (this.name != null && this.name.equals(employee.name)) ); } //need to override hasCode()}
重写hashCode方法:
散列码的定义影响存储在散列集合中的对象的查询效率。
一个好的散列方法通常为不相等的对象产生不相等的散列码。
为每个“关键”域计算散列码,即为equals方法中涉及的域计算散列码,然后再合并。
公式: result = 31 * result + c;
c 为每个域计算的散列码:
1. boolean类型的域,则计算(f ? 1 : 0);
2. byte, char, short, int类型的域, 则计算(int)f;
3. long类型的域,则计算(int)(f^(f>>>32));
4. float类型的域,则计算Float.floatToIntBits(f);
5. double类型的域,则计算Double.doubleToLongBits(f), 然后再按照long类型值计算散列值;
6. 对象引用类型的域,则调用这个对象的散列函数
7. 数组类型的域,则调用Arrays.hashCode
示例:以上面的Employee类为例,employeeId 和 name是关键域。
@Override public int hashCode() { int result = 17; //一个非0的常量值作为初始值 result = 31 * result + employeeId; result = 31 * result + name.hashCode(); return result; }
散列集合对象通过散列码查找对象,如果一个对象的散列码发生改变,有可能在散列集合中找不到该对象。
public class Test { public static void main(String[] args) { Employee e = new Employee(1, "Sunny"); List<Employee> list = new ArrayList<>(); list.add(e); Set<Employee> set = new HashSet<>(); set.add(e); e.setName("Tom");//change name field, then hash code will be changed System.out.println(list.contains(e)); //print true, it is expected; System.out.println(set.contains(e)); //print false, the object is not found due to hash code changed set.remove(e); System.out.println(set.size()); //print 1, not able to be removed due to hash code changed set.add(e); System.out.println(set.size()); //print 2, not replace the same object due to hash code changed }}
HashSet是用HashMap来存储对象,键(key)是对象本身;
HashSet中存储的对象,对象的“关键”域(equals方法中的域)应该是不可变的 或 事实不可变的.
HashMap的键(key)如果是对象类型,此键对象的“关键”域(equals方法中的域)应该是不可变的 或 事实不可变的.
- hashcode()和equals()方法
- hashcode() 和 equals()方法
- equals和hashCode方法
- hashcode()和equals()方法
- equals 和 hashcode 方法
- hashcode()和equals()方法
- hashCode()和equals方法
- hashcode()和equals()方法
- hashCode()和equals()方法
- equals和hashcode方法
- equals()和hashCode()方法
- hashcode和equals方法
- equals和hashcode方法
- hashCode和equals方法
- equals和hashcode方法
- hashcode和equals方法
- Equals 方法和 HashCode方法
- equals方法和hashCode方法
- 编程基础题-4
- Unity keystore的小问题
- sql 语句大全
- 基于UDP的回声服务器/客户端
- [日常]JSCPC2017游记
- equals方法 和 hashCode方法
- error: 'isinf' or 'isnan' or 'iserr' was not declared in this scope问题解决
- ActivityManager原理认识笔记
- POJ 1164 The Castle 笔记
- ES6 解构赋值
- 关于在线程中使用AfxGetMainWnd()出错的问题,终于找到了
- Java Socket编程
- 成功在mini2440上移植ffmpeg
- vue常用过滤器