equals()
equals()方法只能用来判断两个对象是否相等,不能用于判断基本数据类型的变量。equals()存在于 Object类中且它是所有类的父类,所以所有类都有equals方法。
1 | /** |
根据类是否重写了equals()方法,有两种情况:
- 未重写:使用的默认是
Object类的equals(),等价于通过==比较。 - 重写:如果两个对象的每个属性都相等,则返回
true,否则返回false。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21/**
* 调用 equals() 的两种情况
*/
class Person {
public String name;
public Person(String name) {
this.name = name;
}
}
Person person1 = new Person("bill");
Person person2 = new Person("frank");
String string1 = new String("ab");
String string2 = new String("ab");
// String 类重写了 equals 方法,返回 true
System.out.println(string1.equals(string2));
// Person 类没有重写 equals 方法,返回 false
System.out.println( person1.equals(person2));
== 和 equals()
区别:
equals()是方法,而==是操作符。- 对于基本类型,
==是比较值的大小是否相同;而对于引用数据类型,==比较的是对象的内存地址是否相同。因为 Java 只有值传递,所以对于
==来说,不管是比较基本数据类型还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量的值是内存地址。
1 | /** |
重写 equals()
思路:
如果是同一个对象的引用,直接返回
true;如果比较对象为空或者不为同一个类型,直接返回
false;将
Object对象进行转型后,判断每个属性或关键域是否相等;
1 | /** |
hashCode()
- 因为
hashCode()定义在Object类中,所以任何类都包含hashCode()。 - 因为计算哈希值具有随机性,所以两个值不同的对象可能计算出相同的哈希值。
1
2
3
4
5
6/**
* Object 的 hashCode()
* native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的 HashMap。
*/
public native int hashCode()Object的hashCode()是本地方法,是通过 C 或 C++ 实现的,通常用来将对象的内存地址转换为整数。
hashCode() 和 equals()
hashCode()和equals()的关系:
- 两个对象的哈希值相等,
equals()不一定返回true(哈希碰撞)。 - 两个对象的哈希值不相等,
equals()一定返回false。 equals()返回true时,两个对象的哈希值一定相等。重写 equals 方法时也需要重写 hashCode 方法,这是因为:必须保证 equals 方法判断两个对象相等时,hash 值也相等。
重写 hashCode()
重写hashCode,可以使用Objects.hash()方法实现,通过类的所有属性生成最终的哈希值。
1 | /** |
Objects.hash()中调用了Arrays.hashCode(),通过循环将每一个属性的哈希值都计算在内:
1 | // Objects.hash() |
toString()
返回类的名字实例的哈希值的 16 进制字符串,所有的子类最好重写 toString 方法。
1 | /** |
clone()
1 | /** |
重写 clone()
clone()在Object中的权限修饰符为protected,所以如果一个类不显式重写clone(),那新建类时就不能调用该类实例的clone()方法。
1 | public class CloneExample { |
类在重写clone()时还需要实现Cloneable接口,不然会抛出CloneNotSupportedException异常。
1 | public class CloneExample { |