1.简单类型的变量没有equals和hashcode方法,只能应用==进行比较;
2.变量,==比较的是对象在堆内存中的地址,如果要比较其中的内容的话,就要用equals方法。
如果是自己定义的对象,没有重写equals方法,那==和equals意义是一样的,都是比较该对象的存放地址。因为Object 的equals方法,就是用==来实现的(可以看源码)。
3.hashcode
就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映 射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。
一般情况不用了解,但是在用到HashMap或者HashSet时候,这个方法就得关注了。
HashSet(无序,不可重复):基本数值类型的直接==比较就能确定是不是相同;当要存入的是引用型变量或者对象时,保证不可重复要实现2重比较:首先比较两个对象的hashcode值,如果hashcode值相同,则再通过equals比较,再相同的话才能确定是同一个对象,不添加。否则就可以添加进HashSet。
HashMap,你想通过一个object的key来拿hashmap的value,hashmap的工作方法是,通过你传入的object的hashcode在内存中找地址,当找到这个地址后再通过equals方法来比较这个地址中的内容是否和你原来放进去的一样,一样就取出value。
举例说明一下:
1.两个Man对象,存储内容一致,都没有重写hashcode和equals方法
Man man = new Man("liming", 25, "lili");
Man man1 = new Man("liming", 25, "lili");
Set<Man> set = new HashSet<Man>();
set.add(man);
set.add(man1);
System.out.println(set.size());
得到的size是2
2.两个man对象,存储内容不一致,但是自定义了hashcode和equals比较规则
@Override
public int hashCode()
{
// TODO Auto-generated method stub
return 123;
}
@Override
public boolean equals(Object obj)
{
Man man = (Man) obj;
return man.age == this.age;
}
Man man = new Man("liming", 25, "lili");
Man man1 = new Man("limingasd", 25, "liliasd");
Set<Man> set = new HashSet<Man>();
set.add(man);
set.add(man1);
System.out.println(set.size());
再调用1里面的代码,得到的结果是1。