平时开发过程中,有时需要重写javaBean的hashCode和equals方法,但是一时间却不知道如何编写,百度上一搜索各种写法,总感觉没一个是标准写法。还好,Lombok的@Data会自动给JavaBean填充hashCode和equals方法,可以通过反编译出来,学习下Lombok如何重写hashCode和equals方法的。
import lombok.Data;
import java.util.List;
/**
* @author sunchangtan
* @date 2019/2/15 13:18
*/
@Data
public class Person {
private String name;
private int age;
private List<Friend> friendList;
private Person[] parents;
private Nation nation;
}
使用jd-gui.exe反编译出class字节码,代码如下:
package com.sample.mybatis.test;
import java.util.Arrays;
import java.util.List;
public class Person
{
private String name;
private int age;
private List<Friend> friendList;
private Person[] parents;
private Nation nation;
public void setAge(int age)
{
this.age = age;
}
public int hashCode()
{
int PRIME = 59;int result = 1;Object $name = getName();result = result * 59 + ($name == null ? 43 : $name.hashCode());result = result * 59 + getAge();Object $friendList = getFriendList();result = result * 59 + ($friendList == null ? 43 : $friendList.hashCode());result = result * 59 + Arrays.deepHashCode(getParents());Object $nation = getNation();result = result * 59 + ($nation == null ? 43 : $nation.hashCode());return result;
}
protected boolean canEqual(Object other)
{
return other instanceof Person;
}
public boolean equals(Object o)
{
if (o == this) {
return true;
}
if (!(o instanceof Person)) {
return false;
}
Person other = (Person)o;
if (!other.canEqual(this)) {
return false;
}
Object this$name = getName();Object other$name = other.getName();
if (this$name == null ? other$name != null : !this$name.equals(other$name)) {
return false;
}
if (getAge() != other.getAge()) {
return false;
}
Object this$friendList = getFriendList();Object other$friendList = other.getFriendList();
if (this$friendList == null ? other$friendList != null : !this$friendList.equals(other$friendList)) {
return false;
}
if (!Arrays.deepEquals(getParents(), other.getParents())) {
return false;
}
Object this$nation = getNation();Object other$nation = other.getNation();return this$nation == null ? other$nation == null : this$nation.equals(other$nation);
}
public void setNation(Nation nation)
{
this.nation = nation;
}
public void setParents(Person[] parents)
{
this.parents = parents;
}
public void setName(String name)
{
this.name = name;
}
public String toString()
{
return "Person(name=" + getName() + ", age=" + getAge() + ", friendList=" + getFriendList() + ", parents=" + Arrays.deepToString(getParents()) + ", nation=" + getNation() + ")";
}
public void setFriendList(List<Friend> friendList)
{
this.friendList = friendList;
}
public String getName()
{
return this.name;
}
public int getAge()
{
return this.age;
}
public List<Friend> getFriendList()
{
return this.friendList;
}
public Person[] getParents()
{
return this.parents;
}
public Nation getNation()
{
return this.nation;
}
public static void main(String[] args) {}
}
hashCode方法:
从上述代码中,可整理下hashCode公式
public int hashCode() {
int PRIME = 59;
int result = 1;
Object $name = getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
result = result * 59 + getAge();
long $height = Double.doubleToLongBits(getHeight());
result = result * 59 + (int) ($height >>> 32 ^ $height);
Object $friendList = getFriendList();
result = result * 59 + ($friendList == null ? 43 : $friendList.hashCode());
result = result * 59 + Arrays.deepHashCode(getParents());
Object $nation = getNation();
result = result * 59 + ($nation == null ? 43 : $nation.hashCode());
return result;
}
-
hashCode计算公式:((59+第一个变量的hashCode) * 59 + 第二个变量的hashCode) * 59 + 第三个变量的hashCode + 。。。 以此类推
-
int、long变量的hashCode值: 变量值
-
double、float变量的hashCode值:需要特殊除了,先转换为longBits,比如
Double.doubleToLongBits
, 再(int) ($height >>> 32 ^ $height)
-
对象型变量的hashCode值:调用hashCode()方法获取
-
数组型变量的hashCode值:调用Arrays.deepHashCode()方法获取
-
变量是null: 默认是取43
equals方法:
protected boolean canEqual(Object other) {
return other instanceof Person;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Person)) {
return false;
}
Person other = (Person) o;
if (!other.canEqual(this)) {
return false;
}
Object this$name = getName();
Object other$name = other.getName();
//字符串变量的比较
if (this$name == null ? other$name != null : !this$name.equals(other$name)) {
return false;
}
//整型变量的比较
if (getAge() != other.getAge()) {
return false;
}
//浮点型变量比较
if (Double.compare(getHeight(), other.getHeight()) != 0) {
return false;
}
Object this$friendList = getFriendList();
Object other$friendList = other.getFriendList();
// 集合对象的变量比较
if (this$friendList == null ? other$friendList != null : !this$friendList.equals(other$friendList)) {
return false;
}
//数组型变量的比较
if (!Arrays.deepEquals(getParents(), other.getParents())) {
return false;
}
Object this$nation = getNation();
Object other$nation = other.getNation();
//一般对象的变量比较
return this$nation == null ? other$nation == null : this$nation.equals(other$nation);
}