今天在看代码的时候,想总结下实际开发中为何要重写类的equals()方法以及hashCode()的原因
代码如下:
public boolean equals(Object o) {
if (this == o) return true;//为了比较的效率
if (o == null || getClass() != o.getClass()) return false;//也是为了比较的效率
Product product = (Product) o;
return sales == product.sales &&
Objects.equals(id, product.id) &&
Objects.equals(name, product.name) &&
Objects.equals(price, product.price);
}
public int hashCode() {
return Objects.hash(id, name, sales, price);
}
白嫖怪来了,请参考以下链接:
https://blog.csdn.net/qing0706/article/details/50593823
看完上面的帖子有点疑惑,就是equals()方法中的,getClass()方法的作用,如何两者的class对象不相等,为何就直接判定这两个类不相等呢?看了以下文章:
https://blog.csdn.net/expect521/article/details/79139829
知道了getClass()方法的作用:返回运行类的类型,如何两个类的类型都不一样了,那两者还相等个屁啊!嗯,所以返回false
另外也知道了重写equals()方法时记得也重写hashCode()方法,这样才完整嘛,至于为什么,参考第一个链接,里面说到了原因。
另外对于以下代码还有点疑惑:
Objects.equals(id, product.id) &&
Objects.equals(name, product.name) &&
Objects.equals(price, product.price);
查阅了Java手册,原来除了一个Object超类之外,还有一个Objects类,其除了继承自object的equals()方法,自身还有一个静态的equals()方法,参数为两个,是比较两者的引用是否相同的,源码如下,总的目的就是比较两者的内容或者引用是否相同:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
这里先说明一下,字符串类也就是String类型的已经重写了equals()方法,比较的是两者的内容是否相同,源代码如下所示(字符串的引用相同,内容当然也就是相同的):
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
下面是Objec类的equals()方法源代码:
public boolean equals(Object obj) {
return (this == obj);
}
有关于==以及equals()方法的详细介绍,请参考以下链接:
https://www.cnblogs.com/naihuangbao/p/9445027.html
那么在idea中如何快速生成这两个方法,直接按住alt+insert或者直接右键选择Generate(生成)选择对应的方法即可:
其实这里有三种选择,但是最后的结果都一样的,可以参考如下链接:
https://www.cnblogs.com/baizhanshi/p/8358142.html
上图选择的是JDK7后的风格
选择equals方法中要比较的字段
选择hashCode()方法中要比较的字段
这里需要注意啦,:Select all non-null fields 也就是选择所有非空字段的意思,那这句话是什么意思呢?去找了下idea的使用手册,是这样解释这个页面的:
This page appears if any of the chosen fields are of non-primitive type in order to avoid generation of unnecessary checks. In other words, if a check box for any of these fields is selected, it is presumed that such field never has a null value and such check will not be included into generated methods.
Click Finish to complete the wizard and create eqauls() and hashCode() methods.
知道你看不懂英文,中文意思如下:
如果所选字段为非基元类型,则显示此页,以避免生成不必要的检查。换句话说,如果选中这些字段中的任何一个字段的复选框,则假定该字段从来没有空值,这样的复选框将不会包含到生成的方法中。
也就是如果选上了,则编译器会认为你这个字段任何时刻都不是空值,会带来不必要的麻烦,最好还是不要选,idea默认的也是不选上的,因为在初始化的时候,没有赋值的话是有可能为空值的,如果选上了这个复选框就会导致报错。
最后点击Finish即可
就可以快速重写这两个方法了。具体的操作也可以参考如下链接:
https://jingyan.baidu.com/article/da1091fb5d8f6b027849d691.html