# equals()
equals() 只能用来判断两个对象是否相等,不能用于判断基本数据类型的变量。equals() 存在于 Object 类中,所以所有类都有 equals(),因为 Object 类是所有类的父类。
public boolean equals(Object obj) {return (this == obj);}
根据类是否重写了 equals(),使用 equals() 有两种情况:
- 未重写:使用的默认是 Object 类的 equals(),等价于通过 == 操作符比较。
重写:如果两个对象的每个属性都相等,则返回 true,否则返回 false。 ```java 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”);
System.out.println(string1.equals(string2)); // String类重写了equals方法,返回true System.out.println( person1.equals(person2)); // Person类没有重写equals方法,返回false
<a name="Yk037"></a>## | == 和 equals()- equals() 是方法,而 == 是操作符。- == 对于基本类型和引用类型的作用效果是不同的:- 对于基本数据类型,== 比较的是值;- 对于引用数据类型,== 比较的是对象的内存地址;> 因为 Java 只有值传递,所以,对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址。```javaInteger i1 = 288;Integer i2 = 288;int i3 = 288;int i4 = 288;System.out.println(i1 == i2); // 比较引用数据类型,返回falseSystem.out.println(i3 == i4); // 比较基本数据类型,返回true
| 重写 equals()
重写 equals() 的思路:
- 检查是否为同一个对象的引用,如果是直接返回 true;
- 检查是否是同一个类型,如果不时,直接返回 false;
- 将 Object 对象进行转型;
判断每个属性或关键域是否相等;
public class EqualsExample {private int x;private int y;private int z;public EqualsExample(int x, int y, int z) {this.x = x;this.y = y;this.z = z;}@Overridepublic boolean equals(Object obj) {if (this == 0) return ture;if (obj == null || obj.getClass() != this.getClass()) return false;EqualsExample that = (EqualsExample) obj;if (x != that.x) return false;if (y != that.y) return false;return z == that.z;}}
# hashCode()
hashCode() 定义在 Object 类中,所以任何类都包含 hashCode()。
hashCode() 返回哈希值,但是因为计算哈希值具有随机性,所以两个值不同的对象可能计算出相同的哈希值。Object 的 hashCode() 是本地方法,是通过 C 或 C++ 实现的,通常用来将对象的内存地址转换为整数。
/*** native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的HashMap。*/public native int hashCode()/**
| hashCode() 和 equals()
hashCode() 和 equals() 的关系:
- 两个对象的 hash 值相等,equals() 不一定返回 true(哈希碰撞)。
- 两个对象的 hash 值不相等,equals() 一定返回 false。
- equals() 返回 true 时,两个对象的 hash 值一定相等。
重写 equals 方法时也需要重写 hashCode 方法,这是因为:必须保证 equals 方法判断两个对象相等时,hash 值也相等。
| 重写 hashCode()
重写 hashCode,可以使用 Objects.hash() 实现,通过类的所有属性值生成最终的 hash 值。
@Overridepublic int hashCode() {return Objects.hash(x, y, z);}
# toString()
返回类的名字实例的哈希值的 16 进制字符串,建议所有的子类重写 toString 方法。
public String toString()
# clone()
protected native Object clone() throws CloneNotSupportedException
| 重写 clone()
clone() 在 Object 中的权限修饰符为 protected,所以如果一个类不显式重写 clone(),那新建类时就不能调用该类实例的 clone() 方法。
public class CloneExample {private int a;private int b;}CloneExample e1 = new CloneExample();CloneExample e2 = e1.clone(); // 报错// 'clone()' has protected access in 'java.lang.Object'
| 实现 Cloneable 接口
类在重写 clone() 时还需要实现 Cloneable 接口,如果一个类没有实现,就会抛出 CloneNotSupportedException。
public class CloneExample {private int a;private int b;@Overridepublic CloneExample clone() throws CloneNotSupportedException {return (CloneExample)super.clone();}}CloneExample e1 = new CloneExample();try {CloneExample e2 = e1.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}// out: java.lang.CloneNotSupportedException: CloneExample
