180. Spring Boot lombok:@EqualsAndHashCode


 

【Video & Communication Platform】

à SpringBoot Video 

http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à  SpringCloud Video

http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share

à Spring Boot source code 

https://gitee.com/happyangellxq520/spring-boot

à Spring Boot communication platform 

http://412887952-qq-com.iteye.com/blog/2321532

  

Origin of need:

       After publishing lombok -related articles, some netizens left a message, it is best to talk about @EqualsAndHashCode .

==============

There is an old saying : Whoever wins the hearts and minds of the people wins the world,

Today there is a cloud : those who have fans will win the world.

==============

 

The requirements of fans are still well met, and @EqualsAndHashCode is more complicated.

 

 

一、@EqualsAndHashCode

There are a few things to know about @EqualsAndHashCode :

( 1 ) This annotation will generate equals (Object other) and hashCode () methods.

( 2 ) It uses non-static, non-transient properties by default.

( 3 ) Some attributes can be excluded through the parameter exclude

( 4 ) Only which properties to use can be specified through the parameter of

( 5 ) By default, it only uses the properties defined in the class and does not call the methods of the parent class

( 6 ) The problem in ( 5 ) can be solved by callSuper=true , so that the method of the parent class is called in the method it generates.

 

 

Second, practice is more fluent

       Well, there is no problem with the theoretical things, let's take a practical look.

2.1 This annotation will generate equals(Object other) and hashCode() methods

 

@EqualsAndHashCode()
public class Girl2 {
	private int id;//主键.
	private String name;//姓名.
	private int age; //年龄.
	private int weight;//体重.
	private int height;//身高.
	
}
 

 

       这里使用了@EqualsAndHashCode注解,那么一旦使用此注解之后会生成hashCode()equals(Object other)方法,具体生成的代码如下:

 

 

	public int hashCode() {
		int PRIME = 59;
		int result = 1;
		result = result * 59 + this.id;
		Object $name = this.name;
		result = result * 59 + ($name == null ? 43 : $name.hashCode());
		result = result * 59 + this.age;
		result = result * 59 + this.weight;
		result = result * 59 + this.height;
		return result;
	}

	protected boolean canEqual(Object other) {
		return other instanceof Girl2;
	}

	public boolean equals(Object o) {
		if (o == this) {
			return true;
		}
		if (!(o instanceof Girl2)) {
			return false;
		}
		Girl2 other = (Girl2) o;
		if (!other.canEqual(this)) {
			return false;
		}
		if (this.id != other.id) {
			return false;
		}
		Object this$name = this.name;
		Object other$name = other.name;
		if (this$name == null ? other$name != null : !this$name.equals(other$name)) {
			return false;
		}
		if (this.age != other.age) {
			return false;
		}
		if (this.weight != other.weight) {
			return false;
		}
		return this.height == other.height;
	}
 

 

     

        对于hashCode()方法生成的时候,跟所有字段的hashCode有关系。

       对于equals()方法就是判断所有的字段是否相等了,如果所有的字段都相等的话,那么就返回true,如果有一个字段不相等的话,就返回false

 

 

2.2 它默认使用非静态,非瞬态的属性。

       这个是怎么理解呢?也就是说变量使用了静态了,或者是瞬态了,那么在生成equalshashcode方法的时候,静态和瞬态的属性是不会参与的。如下的字段定义:

 

  private static int myCode = 1;
  private transient int myCode2 = 2;
   

 

       mycodemyCode2不会参与hashCode的生成,不会参与equasl方法的判断,所以生成的hashCodeequals方法和上面的是一样的。

 

 

2.3 可通过参数exclude排除一些属性

       这个很好理解,就是有些字段不用参与比较,那么就可以排除掉,比如:我们可以判处nameageweightheight属性,通过判断id就能判断两个女孩是否同一个女孩,如下的代码:

 

@EqualsAndHashCode(exclude={"name","age","weight","height"})
public class Girl2{
  private static int myCode = 1;
  private transient int myCode2 = 2;
  private int id;
  private String name;
  private int age;
  private int weight;
  private int height;
}
 

 

       那么对应生成的hashCodeequals方法如下:

 

public int hashCode() {
		int PRIME = 59;
		int result = 1;
		result = result * 59 + this.id;
		return result;
	}

	protected boolean canEqual(Object other) {
		return other instanceof Girl2;
	}

	public boolean equals(Object o) {
		if (o == this) {
			return true;
		}
		if (!(o instanceof Girl2)) {
			return false;
		}
		Girl2 other = (Girl2) o;
		if (!other.canEqual(this)) {
			return false;
		}
		return this.id == other.id;
	}

 

       看到了,方法中只有和id有关系。看到这里有人会有疑问:这要是有n多个字段,但是equals只跟id有关系,那么排除很多的字段,感觉还是很麻烦的,其实有更简单的方式,接着往下看吧。(如果排除的字段比较少,可以使用这种方式)

 

 

2.4 可通过参数of指定仅使用哪些属性

       这里的意思,可以通过of指定我们要的属性,比如:只和id有关系,那么就可以写成如下的代码:

 

@EqualsAndHashCode(of={"id"})
public class Girl2{
  private static int myCode = 1;
  private transient int myCode2 = 2;
  private int id;
  private String name;
  private int age;
  private int weight;
  private int height;
}
 

 

       生成的代码的如下:

 

public int hashCode() {
		int PRIME = 59;
		int result = 1;
		result = result * 59 + this.id;
		return result;
	}

	protected boolean canEqual(Object other) {
		return other instanceof Girl2;
	}

	public boolean equals(Object o) {
		if (o == this) {
			return true;
		}
		if (!(o instanceof Girl2)) {
			return false;
		}
		Girl2 other = (Girl2) o;
		if (!other.canEqual(this)) {
			return false;
		}
		return this.id == other.id;
	}
 

 

       细心的小伙伴会发现,这里生成的代码和在2.3是一样的。对于ofexclude只要还是看属性的多少,如果of配置的属性过多,那么就考虑使用exclude;如果exclude排除的属性过多,那么就应该使用of

 

 

2.5 使用callSuper=true解决继承问题

1)默认仅使用该类中定义的属性且不调用父类的方法

       这个的意思,就是默认情况下,子类的equalshashCode方法,不会调用父类的super.hashCode方法。如下代码:

父类代码:

 

@EqualsAndHashCode
public class Person {
	private int id;
}
 

 

子类代码:

 

@EqualsAndHashCode
public class Girl3 extends Person {
	private String name;
	private int age;
	private int weight;
	private int height;
	
}
 

 

       那么生成的代码为:

 

 

public int hashCode() {
		int PRIME = 59;
		int result = 1;
		Object $name = this.name;
		result = result * 59 + ($name == null ? 43 : $name.hashCode());
		result = result * 59 + this.age;
		result = result * 59 + this.weight;
		result = result * 59 + this.height;
		return result;
	}
	
	 protected boolean canEqual(Object other) {
	        return other instanceof Girl3;
	    }

	public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Girl3)) {
            return false;
        } else {
            Girl3 other = (Girl3)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$name = this.name;
                Object other$name = other.name;
                if (this$name == null) {
                    if (other$name != null) {
                        return false;
                    }
                } else if (!this$name.equals(other$name)) {
                    return false;
                }

                if (this.age != other.age) {
                    return false;
                } else if (this.weight != other.weight) {
                    return false;
                } else if (this.height != other.height) {
                    return false;
                } else {
                    return true;
                }
            }
        }
 

 

       我们会发现这里的的hashCodeequals方法只使用到了子类Girl3的属性,并没有和父类的相关。那么这样就会存在一个问题,id不一样,但是其它属性都一样的情况下,那么就会判断是同一个对象,然后实际上一旦id不一样了,是两个对象,这时候就需要使用到了callSuper=true的属性了,很简单,只需要在Girl3修改如下的代码:

 

@EqualsAndHashCode(callSuper=true)
public class Girl3 extends Person {
	//省略其它代码;
}
 

 

       那么生成的代码如下:

 

protected boolean canEqual(Object other) {
        return other instanceof Girl3;
    }

    public int hashCode() {
        int PRIME = 59;
        int result = super.hashCode();
        Object $name = this.name;
        result = result * 59 + ($name == null ? 43 : $name.hashCode());
        result = result * 59 + this.age;
        result = result * 59 + this.weight;
        result = result * 59 + this.height;
        return result;
    }
    
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Girl3)) {
            return false;
        } else {
            Girl3 other = (Girl3)o;
            if (!other.canEqual(this)) {
                return false;
            } else if (!super.equals(o)) {
                return false;
            } else {
                Object this$name = this.name;
                Object other$name = other.name;
                if (this$name == null) {
                    if (other$name != null) {
                        return false;
                    }
                } else if (!this$name.equals(other$name)) {
                    return false;
                }

                if (this.age != other.age) {
                    return false;
                } else if (this.weight != other.weight) {
                    return false;
                } else if (this.height != other.height) {
                    return false;
                } else {
                    return true;
                }
            }
        }
    }
 

 

       注意:区别就是对于hashCode方法多了如下的代码:

 

int result = super.hashCode();

 

       对于equals方法多了如下代码:

 

else if (!super.equals(o)) {
                return false;
}
       好了本文就介绍到这里了,博主也要洗洗睡了。

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326317212&siteId=291194637