区分一下"==",equals和hashcode
==
对于基本数据类型(byte,short,char,int,float,double,long,boolean),==会判断它们的值是否相等。对于引用数据类型(Byte, Short, Character,Integer,Float, Double,Long, Boolean),则会判断它们的引用(也就是存储地址)是否相等。
String不属于基本数据类型,而是一个类。
equals方法
定义在Object类中,也就是说对于所有的类都可以调用equals方法。equals方法用来检测一个对象是否等于另外一个对象。是来确定两个对象的引用是否相等。如果两个对象引用相等,这两个对象也就肯定相等。这对于大部分的类来说是足够的。经常需要检测对象的状态来判断是否相等。
Java语言规范要求equals方法具有以下特性:(以下x,y,z都为对象引用)
- 自反性:x.equals(x)返回true(x为非空引用)。
- 对称性:如果x.equals(y)返回true,y.equals(x)也应该返回true。
- 传递性:x.equals(y) 返回true,y.equals(z) 返回true,那么x.equal(z) 也返回true。
- 一致性:如果比较的两个对象引用没有发生变化,那么反复调用x.equals(y)应该返回同样的结果。
- 对于任意非空引用x,x.equal(null)返回false。
对于java常用的一些类库,都有自定义的equals方法。我们也可以在自己定义的类中复写equals方法。
在子类中调用equals方法时,首先调用超类的equals方法。如果检测失败,对象就不可能相等。如果超类字段都相等,则需要比较子类的实例字段。
在子类调用equals方法时,有两种不同的情形:
- 如果子类可以有自己的相等性概念,则对称性需求将强制使用getClass检测。
- 如果由超类决定相等性概念,那么就可以使用instanceOf检测,这样可以在不同子类的对象之间进行相等性检测。
对于数组类型的字段,可以使用静态的Arrays.equals方法来检测相应的数组元素是否相等。
hashCode方法
散列码是由对象导出的一个整数值,没有规则。每个对象都有一个默认的散列码,其值由对象的存储地址得出。注意:在StringBuilder类中没有自定义hashCode。
String类使用了以下算法来实现计算散列码:
int hash = 0;
for (int i = 0; i < length(); i++)
hash = 31 * hash +charAt(i);
如果重新定义了equals方法,就必须为用户可能插入散列表的对象重新定义hashCode方法。