【Video & Communication Platform】
http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
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 它默认使用非静态,非瞬态的属性。
这个是怎么理解呢?也就是说变量使用了静态了,或者是瞬态了,那么在生成equals和hashcode方法的时候,静态和瞬态的属性是不会参与的。如下的字段定义:
private static int myCode = 1; private transient int myCode2 = 2;
mycode和myCode2不会参与hashCode的生成,不会参与equasl方法的判断,所以生成的hashCode和equals方法和上面的是一样的。
2.3 可通过参数exclude排除一些属性
这个很好理解,就是有些字段不用参与比较,那么就可以排除掉,比如:我们可以判处name、age、weight、height属性,通过判断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; }
那么对应生成的hashCode和equals方法如下:
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是一样的。对于of和exclude只要还是看属性的多少,如果of配置的属性过多,那么就考虑使用exclude;如果exclude排除的属性过多,那么就应该使用of 。
2.5 使用callSuper=true解决继承问题
(1)默认仅使用该类中定义的属性且不调用父类的方法
这个的意思,就是默认情况下,子类的equals和hashCode方法,不会调用父类的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; } } }
我们会发现这里的的hashCode和equals方法只使用到了子类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; }好了本文就介绍到这里了,博主也要洗洗睡了。