0%

Object类的方法

equals和hashCode

equals

1
2
3
public boolean equals(Object obj) {
return (this == obj);
}

默认使用==比较对象的引用,也就是说如果不去覆写,使用equals==效果是一样的。

hashCode

1
2
@HotSpotIntrinsicCandidate
public native int hashCode();

hashCode()是一个native方法,值由对象的存储地址计算得出(字符串类型的hash值根据字符串内容计算)。

为什么需要覆写equals和hashCode方法

两个方法的作用都是比较两个对象在逻辑上是否相等。equals可靠,而hashCode性能更强。

Object默认的equals和hashCode方法基本没什么用。

所以如果要做大量的对比,可以先用hashCode做第一步筛选,如果hashCode相同再用equals做出最后的判断。

  • 情景一:我有一个List,元素类型是Student(List),我想对List中的元素去重,可以使用List.stream().distinct()方法,但是需要告诉java怎么样的两个Student才能称之为equal。
  • 情景二:HashMap中添加自定义类型的key时,需要覆写equals和hashCode方法,原因要从HashMap的原理说起。

如何覆写equals和hashCode方法

equals方法判断相等,hashCode值必须相等。hashCode值相等,equals方法可以不想等。

所以hashCode相等是equals的必要不充分条件。

覆写equals时需要考虑自反性、对称性、传递性、一致性(离散数学里关系的性质)。

toString

System.out.println()时默认的方法,默认为”类名@hashCode”。

clone

1
2
@HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;

如果对象的类没有实现Cloneable接口,调用clone方法就会抛出CloneNotSupportedException。