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