为什么我们需要
hashcode方法和equals方法
我们都知道,在java中每一个类都继承Object,Object中所以每一个类都有一个hashCode(),equals()方法,为什么要在最高层设计这两个方法呢,先说equals方法。
判断两个对象是否相等,怎么样才算相等,举个
例子
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
System.out.println(i1 == i2);//false
System.out.println(i1.equals(i2));//true
为什么同样是相等,为什么会是不同结果呢,当然这个很简单,用i1 == i2,是比较两个对象是否在同一
内存中,也就是,是不是根本上是同一个对象,而i1.equals(i2)是比较因为Integer对Object的equals方法进行了重写,使equals方法比较 值(value)是否相等。还是贴出jdk的源码实在
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
现在应该很清楚了。
所以现在为什么要设计equals方法在Object中,我们就有了答案,因为任何时候我们定义自己类的时候,我们可以选择是否重写equals方法,增加了灵活性,如果我们不重写,就是继承与Object的equals方法,判断我们对象是否相等。
如果单单比较两个对象是否相等,直接重写equals方法就行~,可是我们进行编程时不可能不用到容器,我们会用到 HashSet,LinkedHashSet,HashMap,LinkedHashMap的容器,只要我们要把我们对象放在容器中,要让我们对象成为 key-value的key时,我们必须正确地重写hashCode()方法,(Object对象的hashCode()方法是把内存地址转化为整数)。
说起HashMap的原理,基本上是哈希表的原理,说起哈希表的原理无非是,哈希函数和冲突解决,函数是某个hash函数(这个函数一定要把冲突减小到最小),输入是键值(key)的hashcode(),根据输入和函数得到value的地址,但这个地址不可避免会出现冲突(即会出现两个同样的value 在同一个槽bucket中),,所以我们需要冲突解决,而冲突解决是通过key的equals方法,来逐一比较,来找到相等的那个。
其实为什么要用hash的方法呢,无非就是想提高性能,关于性能还涉及到初始容量( initial capacity )和负载因子(load factor.),一般我们直接使用默认的就行,jdk对HashMap性能和大小做了很
比较好的折中(tradeoff)。
另外,我们平时用HashMap时,使用String做键值基本上可以满足我们大多数情况的需求,因为String类已经重写了hashCode()方法和equals()方法。