覆盖equals方法时请遵守通用约定
什么情况需要覆盖equals方法?
当需要比较的类有自己的逻辑特点时,而Object的equals方法不能达到预期的效果时,就需要覆盖equals比较类的属性值。
覆盖equals方法的通用约定
自反性——对于任何非null的对象x,都满足x.equals(x)返回true。也就是说对象必须等于自身。
对称性——对于任何非null的对象x和y,当且仅当x.equals(y)返回true时,y.equals(x)必须返回false。也就是说对象x等于y时,对象y必须也等于对象x。
传递性——对于任何非null的对象x、y、z,当x.equals(y)返回true,并且y.equals(z)返回true时,x.equals(z)也必须返回true。也就是说当对象x等于对象y,并且对象y等于对象z时,对象x必须等于对象z。
一致性——对于任何非null的对象x、y,当x.equals(y)返回true,并且对象x、y没有被修改时,多次调用x.equals(y)必须一直返回true,否则一直返回false。
非空性——比较的对象必须为非null的对象。
覆盖equals方法的几点建议:
①使用“==”操作符来判断引用对象是否相等;
②使用instanceof操作符来判断对象类型是否正确;
③对于不是float或者double类型的基本数据类型可以使用==来判断相等,对于引用对象可以调用quals方法;
④覆盖equals方法总要覆盖hashcode方法;
⑤请不要修改equals方法参数中的Object对象;
覆盖equals时总要覆盖hashcode
实现hashcode的通用约定:
①只要没有修改equals比较涉及的属性,多次调用hashcode方法都返回同一个值。
②只要2个对象用equals比较是相等的,那么它们返回的hashcode值必定相等。
③如果2个对象用equals比较是不想等的,那么它们返回的hashcode值不一定不相等。
始终要覆盖toString方法
我个人理解,到底需不需要覆盖toString方法主要看我们的程序中是否需要在控制台打印出来,写好一个toString方法有助于我们获取到更多关于对象中的有用信息。
谨慎的覆盖clone方法
clone方法的目的就是为了创建一个新的对象,那么要想覆盖clone方法就必须要实现cloneable接口,并且针对基本数据类型和引用数据类型的对象的克隆引出浅克隆和深克隆2个概念。
下面这篇文章讲的很到位,值得参考:
https://blog.youkuaiyun.com/jeffleo/article/details/76737560
考虑实现comparable接口
实现了comparable接口就可以在类的内部重写compareTo方法,通过compareTo方法可以实现对象间的比较或排序。
注意:
当包含compareTo方法的对象和有序集合结合使用时,由于有序集合是按照对象内部的compareTo方法比较来增加元素的,这就导致如果2个数值相等的元素增加到集合中时,只存在一个数值。
比如BigDecimal b1 = new BigDecimal(1.0); BigDecimal b2 = new BigDecimal(1.0);同时将b1,b2增加到treeset集合中,首先比较b1.compareTo(b2)返回值为true,所以treeset只存在一个元素。但是如果将b1,b2放到hashMap中时,首先比较b1.equals(b2)返回值为false,所以hashMap中会存在2个元素。
总结:根据集合所以比较对象的方法不同,选择不同的集合,在开发中看实际需要。