可能视频里说的不对,也可能你听的不对 重写hashCode方法的原因是我们经常会使用hashMap。HashMap的工作原理是根据hashCode存放/查找对象。 举例来说你建立了一个Person类,没有重写hashCode方法,但是重写了equals方法,Person p1 = new Person("xiaoming"); Person p2 = new Person("xiaoming");HashSet set = new HashSet(); set.add(p1); set.contains(p1);// line a set.contains(p2);//line b如果你没有实现hashCode方法的话,那么line a 返回true,line b返回false 因为从object哪里继承来的hashCode方法,每个对象都是不一样的 实际上我们使用时通常希望line b也返回true,这样就需要重写hashCode
equals方法在最后判断两个变量是否等于的时候,本质上判断的是这两个变量的hashCode值。 如: public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cardNum == null) ? 0 : cardNum.hashCode()); result = prime * result + ((pwd == null) ? 0 : pwd.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; User other = (User) obj; if (cardNum == null) { if (other.cardNum != null) return false; } else if (!cardNum.equals(other.cardNum))//此处判断依然用到equals方法比较,此时返回判断pwd的hashCode值是否相等 return false; if (pwd == null) { if (other.pwd != null) return false; } else if (!pwd.equals(other.pwd))//同上 return false; return true; }
java的map实现里面对这两个都检测的
并不是说效率低导致的需要重写
转别人的,个人感觉写的挺好,希望对你有帮助
重写hashCode方法的原因是我们经常会使用hashMap。HashMap的工作原理是根据hashCode存放/查找对象。
举例来说你建立了一个Person类,没有重写hashCode方法,但是重写了equals方法,Person p1 = new Person("xiaoming");
Person p2 = new Person("xiaoming");HashSet set = new HashSet();
set.add(p1);
set.contains(p1);// line a
set.contains(p2);//line b如果你没有实现hashCode方法的话,那么line a 返回true,line b返回false
因为从object哪里继承来的hashCode方法,每个对象都是不一样的
实际上我们使用时通常希望line b也返回true,这样就需要重写hashCode
equals是比较他们的值是否相等,在比较值之前 还是要比较hashCode。
学习没有捷径,捷径就是你真的懂了!所以如果不想费力气真正明白,只要记得就成了,事实上这只是理论上的一个问题 web开发这辈子也用不着你覆写hashCode(),方法和equals()方法至少我写了三年也没碰到过这样的事.除了面试时会问
你这样的人就是没看过书的人.
java的map实现里面对这两个都检测的
并不是说效率低导致的需要重写
public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
hashCode 的常规协定是: 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
返回:
此对象的一个哈希码值。
另请参见:
equals(java.lang.Object), Hashtable--------------------------------------------------------------------------------equals
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
equals 方法在非空对象引用上实现相等关系: 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。 注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。
另请参见:
hashCode(), Hashtable
http://blog.csdn.net/qian119110/archive/2010/11/29/6044027.aspx
hashcode
http://blog.csdn.net/qian119110/archive/2010/11/30/6045435.aspx
hashCode()方法时,有个小技巧,就是让对象数值属性和一个素数相乘,,并将积加上,对于对象类型,调用其hashCode()方法即可public class Student {
private String stuNo;
private String stuname;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((stuNo == null) ? 0 : stuNo.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if(obj!=null){
return false;
}
if(!(obj instanceof Student)){
return false;
}
Student stu=(Student)obj;
return this.stuNo==stu.stuNo;
}}
这个说得太绝对了吧!你没用过并不代表做web 这辈子也用不着你覆写hashCode(),方法和equals()
hasnCode相比equals查找时要快 毕竟它是数值类型的 但存在这种可能就是 两个不同的对象 但他们的hashCode 相同 这样在用hashCode查找时就不知道应该查的是哪个对象了 此时就开始比较equals的值
如果两个对象a,b a.equals(b) == true.那么 a.hashCode()和b.hashCode()也必须相等。反之则不是必须。也就是说,推荐保证 hashCode相等是equals为true的必要条件这一规则。如果你重写了equals方法,导致此类的2个实例可能会equals,但是又没有重新hashCode的话,会与以上规则相冲突因此说,重写equals则必须重写hashCode。否则这个类的实力放入HashSet或作为key放入HashMap时,会出错。
如: public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cardNum == null) ? 0 : cardNum.hashCode());
result = prime * result + ((pwd == null) ? 0 : pwd.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;
User other = (User) obj;
if (cardNum == null) {
if (other.cardNum != null)
return false;
} else if (!cardNum.equals(other.cardNum))//此处判断依然用到equals方法比较,此时返回判断pwd的hashCode值是否相等
return false;
if (pwd == null) {
if (other.pwd != null)
return false;
} else if (!pwd.equals(other.pwd))//同上
return false;
return true;
}
而对象的可变性是无限的。拿字符串举例。用大小写字母+数字,共计62个字符,如果生成长度32的字符串有 62的32次方个不同的字符串。而hashCode只能有2的32次方个有限集合。将62的32次方个不同的字符串的hashCode映射到2的32次方里去,将导致很多字符串的hashCode是一样的。而这些字符串显然不互相equals
Long,有2的64次方个不同的数值。而其hashCode只能有2的32次方个不同的数值
很显然,平均将有 2的64次方除以2的32次方个Long共用一个hashCode值