Map怎么使用自定义引用类型做主键

来源:互联网 发布:wind资讯金融数据终端 编辑:程序博客网 时间:2024/06/05 06:58

问题演示

import java.util.HashMap;import java.util.Map;class Student{    private String name = "张三";    private String tel = "123";}public class TestJson {    public static void main(String[] args) {         Student st1 = new Student();         Student st2 = new Student();         Map<Student, String> map = new HashMap<Student, String>();         map.put(st1, null);         map.put(st2, null);         System.out.println(map.size());    }}

如上代码,st1,st2属性完全一样,分别使用st1,st2作为主键存入map,发现map结果等于2,为什么不是1呢?

map的存储结构有点像一个树,有很多节点,每个节点又是一个链表;
我们put一条数据时,先调用主键对象的hashcode方法找到对应的节点,
然后遍历这个节点对应的链表,使用equals方法比较是否存在和自己相同的主键;

我们调用 st1.hashcode == st2.hashcode发现是false,当然默认的equals方法取得是对象地址,肯定也是不相等,这个时候hashcode不相等,就找到不同的节点,equals方法不相等,就找不出相同的主键;
因此如果Map要是用自定义引用类型做主键,需要重写hashcode、equals方法;

class Student{    private String name = "张三";    private String tel = "123";    public int hashCode() {         int result = 17;              result = result * 31 + name.hashCode();              result = result * 31 + tel.hashCode();              return result;    }    public boolean equals(Object  obj) {        Student st = (Student)obj;        if(null != st) {            return StringUtils.equals(st.name, st.name) && StringUtils.equals(st.tel, st.tel);        }        return false;    }}public class TestJson {    public static void main(String[] args) {         Student st1 = new Student();         Student st2 = new Student();         Map<Student, String> map = new HashMap<Student, String>();         map.put(st1, null);         map.put(st2, null);         System.out.println(map.size());    }}