-
理解equals()方法和==运算符的区别是非常重要的。
- 默认情况下(即没有被重写时)equals()只能比较引用类型,"=="既能 比较引用类型又能比较基本类型。
- equals()方法从Object类继承,即比较对象引用的值
- 一般都被子类方法覆盖,不再比较引用的值
-
"=="运算符:
- 比较基本数据类型:相当于算术等号。
- 比较引用数据类型:比较引用的值,不能被覆盖。
-
通常情况,子类要重写equals( ),改变它的含义。所以有的类中 equals( )是比较地址,有的类中该方法就不比较地址,具体的,就看子类新定义的该方法的规定。建议看看包装类中的equals()方法,蛮有趣的。
-
在Java中有个规定:如果equals( )返回两个对象是相等的,那这两个对象上调用hashCode( )返回的整数必须相等。否则在使用Hash类型集合时就会产生错误。
-
注意:覆盖equals( )方法同时,还要记得覆盖hashCode( )方法。 需要说明,如果equals( )返回两个对象不等,它们的hashCode( )也 可以返回相同的整数。但是最好让它们的hashCode( )返回不同的整 数,这有利于提高Hash类型集合的性能。
-
重写equals方法时,一定要重写hashcode()方法吗?
-
hashcode的调用的条件:
- 想往map里面放一个类作为map的键值,这个类又是自己设计的;
- 虽然类不是自己写的,但是你修改了这个类的equals方法;
-
如果满足上述调用条件,就要注意重写hashcode方法。 这样 当你往map 里放值得时候,系统会调用这个对象的.hashcode()方法来生成相应的 hash值,来映射相应的对象。
-
-
如果同一个类的两个对象的属性值相等,那么他们的hashcode一定相等吗?这个要看你具体如何实现你的hashcode,如果你希望他们的值一样hashcode也一样,你就可以这样实现。 但是hashcode的实现,一般要满足几个特征,比如自反性、对称性、传递性那些。
离散数学的知识:
设R是A上关系,若R是自反的、对称的和传递的,则称R是A中的等价关系。 若 a , b ∈ A ,且 a R b ,则称 a 与 b 等价 若 a,b\in A,且aRb,则称a与b等价 若a,b∈A,且aRb,则称a与b等价。
equals() 其实就是一种等价关系,它指定了某种方法(默认的hashCode()、重写的hashCode()、自定义的equals()判据等)来判定这种等价关系。
我们自己想要重写equals(),为了保证这种等价关系,就需要维护自反性、对称性、传递性。
其实,简单的测试还不太够,最好是有形式化的证明。
这篇文章中就涉及了equals()的自反性、对称性、传递性,做了简单的测试。
IDE自动生成equals( )和hashCode( )如果你确实懒得重写equals()和hashCode(),IDE支持自动生成这两个方法。
首先,Person类已经完成到了这个程度:
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Integer age;
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
}
}
Eclipse
import java.io.Serializable;
import java.util.Objects;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Integer age;
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Person)) {
return false;
}
Person other = (Person) obj;
return Objects.equals(id, other.id) && Objects.equals(name, other.name);
}
}
IntelliJ IDEA
import java.io.Serializable;
import java.util.Objects;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Integer age;
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(id, person.id) &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
String的hashCode( )
String有hash这个实例变量,它的定义如下:
private int hash; // Default to 0
它缓存了hashCode()方法的值,也就是说,第一次调用hashCode()的时候,会把结果保存在hash这个变量中,以后再调用就直接返回保存的值。
我们来看下String类的hashCode方法,代码如下:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?