java map 重写equals_java 重写类的equals()和hashCode()方法

今天在用阿里代码检查工具检查项目的时候,发现了一个警告

Map/Set的key为自定义对象时,必须重写hashCode和equals

说明为:

1) 只要重写equals,就必须重写hashCode。

2) 因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。

3) 如果自定义对象做为Map的键,那么必须重写hashCode和equals。

下面是代码的写法(伪代码)

public void methodDemo(){

Set hashSet = new HashSet();

hashSet.add(new ObjDemo("1","对象1"));

hashSet.add(new ObjDemo("2","对象2"));

}

ObjDemo类很简单

class ObjDemo{

private String id;

private String name;

public ObjDemo(String id,String name){

this.id = id;

this.name = name;

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

为什么会报这个警告?

警告中也说明了,因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须重写这两个方法。

equals和hashCode的关系(这个是规定):

1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;

2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)

hashCode()方法是干什么的,这里提示了是重写,那么原来其实是有一个hashCode的,在Object类中,这里的hashCode()存放的是对象的内存地址

所以我们在存放对象进入hashSet的时候,如果不重写equals()和hashCode(),像下面这段代码

public void methodDemo(){

Set hashSet = new HashSet();

hashSet.add(new ObjDemo("1","对象1"));

hashSet.add(new ObjDemo("1","对象1"));

}

其实我们逻辑上放进去的是一个对象,因为id、name都相等,但是,如果打断点或者写个测试方法去输出hashSet长度的时候,会发现在hashSet中却有两个对象,因为这两个对象的内存地址是不同的。所以要重写equals()和hashCode()方法。例如根据id来比较两个对象是否相等,以及根据id取hashCode,在ObjDemo中加入

@Override

public boolean equals(Object o) {

if (o instanceof ObjDemo){

ObjDemo obj = (ObjDemo)o;

return id.equals(obj.id);

}

return false;

}

@Override

public int hashCode() {

return Objects.hash(id);

}

这样往hashSet中放对象时就会根据id去判断,不会重复添加。

面试题:为什么重写equals()方法要重写hashCode()方法

从上面的规定可以知道,如果只重写了equals()方法不重写hashCode()方法,那么则违反了如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同

也可以把上面的代码中的hashCode()方法去掉,添加2个id为1的对象,set集合里的数据还是为2条。

所以得出结论:如果一个类重写了equals方法但是没有重写hashCode方法,那么该类无法结合所有基于散列的集合(HashMap,HashSet)一起正常运作。

你可能感兴趣的:(java,map,重写equals)