hash code、equals是Java用来比较对象是否相等,下面介绍一下自己在工作中对hash code、equals的使用. 首先介绍下String类中的hashCode、equals方法:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
上面就是String类的hashCode、equals方法,如果两个字符串对象相等,它们的hash code一定相等,Java比较两个对象是否相等,首先比较hash code是否相等,如果相等,再通过equals方法判断是否相等;若hash code不等,两个对象肯定不等. CollectionUtils提供的方法非常方便我们对集合的操作:
List<String> aList = new ArrayList<String>();
aList.add("l");
aList.add("i");
List<String> bList = new ArrayList<String>();
bList.add("o");
bList.add("i");
List<String> abList = (List<String>) CollectionUtils.subtract(aList,bList);
abList.stream().forEach(System.out::println);
List<Integer> cList = new ArrayList<Integer>();
cList.add(1);
cList.add(2);
List<Integer> dList = new ArrayList<Integer>();
dList.add(1);
dList.add(3);
List<Integer> cdList = (List<Integer>) CollectionUtils.subtract(cList,dList);
cdList.stream().forEach(System.out::println);
上面打印出来的结果应该不出所料:l、2,由于String、Integer重写了Object的hashCode、equal方法,如果集合中存的是自定义对象,结果又是如何呢:
List<UserInfoEntity> eList = new ArrayList<>();
eList.add(new UserInfoEntity().setMobile("1").setName("w"));
eList.add(new UserInfoEntity().setMobile("3").setName("l"));
List<UserInfoEntity> fList = new ArrayList<>();
fList.add(new UserInfoEntity().setMobile("1").setName("w"));
fList.add(new UserInfoEntity().setMobile("5").setName("p"));
List<UserInfoEntity> efList = (List<UserInfoEntity>) CollectionUtils.subtract(eList,fList);
efList.stream().forEach(System.out::println);
UserInfoEntity:
public class UserInfoEntity{
private String name;
public String getMobile() {
return mobile;
}
public UserInfoEntity setMobile(String mobile) {
this.mobile = mobile;
return this;
}
private String mobile;
public String getName() {
return name;
}
@Override
public String toString() {
return "name="+getName()+",mobile="+getMobile();
}
public UserInfoEntity setName(String name) {
this.name = name;
return this;
}
}
结果却出乎所料,原因在于我们没有重写Object的equals、hashCode方法,按照实际需要重写即可:
@Override
public int hashCode() {
return name.length() * 31 + mobile.length();
}
@Override
public boolean equals(Object obj) {
UserInfoEntity otherObj = (UserInfoEntity) obj;
if (this.getMobile().equals(otherObj.getMobile()) && this.getName().equals(otherObj.getName())) {
return true;
}
return false;
}
对于hashCode方法,重写equal方法,一定要重写hashCode方法,在集合HashSet中存储的元素不能相同,所以操作时需要注意.