public class Test1 {
int i = 1;
@Override
public int hashCode() {
return 1;
}
public static void main(String[] args) {
Set set = new HashSet();
set.add(new Test1());
set.add(new String("ABC"));
set.add(new Test1());
System.out.println(set);
System.out.println(set.size());
}
老哥们,我重写了hashCode方法 会改变对象底层的哈希码值吗?因为修改后在set中的值就一样了,却没被equals干掉
你要是在set中不重复出现,还得重写equal方法
package collection;
import java.util.*;
class Person
{
private String name;
private String address;
private int age;
Person(String name,int age,String address){
this.name = name;
this.address=address;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
class HashCodeDemo
{
public static void main(String[] args)
{
Set<Person> s = new HashSet<Person>();
Person p = new Person("拉格朗日",20,"珠海");
Person p1 = new Person("拉格朗日",20,"珠海");
System.out.println("p.hashCode=" + p.hashCode());
System.out.println("p1.hashCode=" + p1.hashCode());
s.add(p);
s.add(p1);
System.out.println(s.size());
}
}
输出结果:
p.hashCode=1690552867
p1.hashCode=1690552867
1
在Java中,哈希码用于等效性比较和散列表的查找位置。如果两个对象根据equals方法是等效的,则这两个对象必须生成相同的哈希码。因此,当你重写一个类的hashCode方法时,必须确保它不仅仅是使用默认的Object.hashCode()的版本,而且必须采用一个算法,使得哈希码是一个可靠的指示等效性的数值。出于这个原因,建议同时在重写equals方法的同时重写hashCode方法,以确保一致性。一个常见的方式是用对象中的关键域计算哈希码。例如,假设你有一个Person对象,且你想根据其姓名和年龄来比较对象,那么你可以重写它的hashCode方法如下:
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + age;
return result;
}
其中,31是一个不同于其他数的质数,也不是2的幂,具有很好的离散性质。
然后回答下问题,重写hashCode方法会改变对象的哈希码值,因为默认的hashCode实现是返回对象内存地址的哈希码,而重写hashCode,使用不同的算法来计算哈希码,因此相同hashCode值的对象也会被当作同一个对象。
如果你的类中有两个对象通过equals方法认为它们是相同的,那么你就需要在这个类中重写hashCode方法,以使得这两个对象有相等的哈希码值。你可以遵循以下三个步骤:
声明一个int变量result,并将其初始化为对象某个非零常数值。
对于对象中每个关键域f,完成以下步骤:
a. 为该域计算int类型的哈希码c。
b. 合并哈希码:result = 31 * result + c。
重写hashCode如下:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + field1.hashCode();
result = 31 * result + field2.hashCode();
...
result = 31 * result + fieldN.hashCode();
return result;
}
这样就能够使相等的对象拥有相等的哈希码值了。