hashCode:表示一个对象是唯一的,有一串数字+字母组成。
如果不能唯一确定一个对象,hashmap(对象,值)你怎么能通过key,查找到相应的值?
哪么hashCode如何产生的,挺重要吧!在 in Effection java 有一套规则,
1》当你自己写一个类时,可以重新hashcode()方法,表示如何去唯一确定一个对象
2》equals(),也需要重写,java自己写的类默认是内容比较,但是我们自己写的类默认是对象地址比较。
一、例子:本来想通过员工号去确定一个每一个人,明明每一个实例对象都保存了,预测值也保存了。
1>当新建员工号对象,竟然查不着对应预测值,失望啊!
2>难道一个的对象的hashcode出现问题了
3>难道一个的对象的equal()出现问题了.
证明equals()是地址比较,所以当一个实例对象不能作为key时,必须重写(override) hashcode(),equals()。
1、StorePersonNum :每一个人对应一个员工号
2、Prediction :根据员工号去预测员工有特长,无特长。
3、PersonDetector :把HashMap(员工号对象,预测对象)保存下来。
4、新建立一个kdy:员工号3对象,按理说有3号员工,但是找不到对应值。所以equals()方法出现问题了。
package containers;
public class StorePersonNum {
protected int number;
public StorePersonNum(int n) { number = n; }
public String toString() {
return "店里员工#" + number;
}
}
package containers;
import java.util.*;
public class Prediction {
private static Random rand = new Random(47);
//这里是随便测试一下,根据实际进行变化
private boolean personsum = rand.nextDouble() > 0.5;
public String toString() {
if (personsum)
return "表示员工有特长!";
else
return "表示员工无特长!";
}
}
package containers;
import java.lang.reflect.*;
import java.util.*;
import static net.mindview.util.Print.*;
public class PersonDetector {
/**<T extends StorePersonNum>表示这是一个方法参数通用
* 表示方法里要用StorePersonNum类型或它的子类
* Class<T>:表示所有类。
*/
public static <T extends StorePersonNum> void detectSpring(Class<T> type)
throws Exception {
/** 通过反射建立对象(当类已经装入内存后)
* 通过构造函数的类(int)型得到类对象连接
* 得到类对象连接后,建立对应的实例(对象)
* */
Constructor<T> storep = type.getConstructor(int.class);
Map<StorePersonNum, PersonDetector> map = new HashMap<StorePersonNum, PersonDetector>();
for (int i = 0; i < 10; i++)
map.put(storep.newInstance(i), new PersonDetector());
print("map = " + map);
/** 新建立一个对象,内容相同,但是对象地址不一样,
* map.containsKey(sp):默认调用equals()方法。
* */
StorePersonNum sp = storep.newInstance(3);
print("寻找店里员工: " + sp);
if (map.containsKey(sp))
print(map.get(sp));
else
print("Key没发现店里员工:" + sp);
}
public static void main(String[] args) throws Exception {
detectSpring(StorePersonNum.class);
}
}
|
二、重写object.override(),equals()方法,因为实例对象不能作为key值了。
number == ((StorePersonNum2) o).number):表示原来保存在hashmap(numeber) 和传过来的对象的number比较
o instanceof StorePersonNum2:instanceof 表示保存的对象是否属于StorePersonNum2 类,因为我刚加的,
所以要确定新建的对象属于新加的类,才能正确取出相应员工号对应的值。
package containers;
public class StorePersonNum2 extends StorePersonNum {
public StorePersonNum2(int n) {
super(n);
}
public int hashCode() {
return number;
}
public boolean equals(Object o) {
return o instanceof StorePersonNum2 && (number == ((StorePersonNum2) o).number);
}
}
package containers;
public class PersonDetector2 {
public static void main(String[] args) throws Exception {
PersonDetector.detectSpring(StorePersonNum2.class);
}
}
|
@1db9742:圈后面是hashcode值, jvm 除了你重写的hashcode()值+加了他们自己产生的值。
结果:
map = {
店里员工#0=containers.PersonDetector@1db9742,
店里员工#1=containers.PersonDetector@106d69c,
店里员工#2=containers.PersonDetector@52e922,
店里员工#3=containers.PersonDetector@25154f,
店里员工#4=containers.PersonDetector@10dea4e,
店里员工#5=containers.PersonDetector@647e05,
店里员工#6=containers.PersonDetector@1909752,
店里员工#7=containers.PersonDetector@1f96302,
店里员工#8=containers.PersonDetector@14eac69,
店里员工#9=containers.PersonDetector@a57993}
寻找店里员工: 店里员工#3
containers.PersonDetector@25154f