MENU

HashMap用可变对象作为key踩坑

前言

在Java道路上越踩越多坑,最近被问到一个知识点,当对象作为HashMap一个key时,再未重写equalshashcode方法时候,get方法返回的值为null

分析

在下面一段代码中,未重写equals以及hashCode方法情况下,输出结果为null

import java.util.HashMap;
import java.util.Map;

class People {
    private String name;

    public People() {
    }

    public People(String name) {
        this.name = name;
    }

    public static void main(String[] args) {
        Map<People, Integer> map = new HashMap<People, Integer>();
        map.put(new People("icharle"), 18);
        
        System.out.println(map.get(new People("icharle")));
    }
}

# 输出结果为null

改造后代码:

import java.util.HashMap;
import java.util.Map;

class People {
    private String name;

    public People() {
    }

    public People(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }

        People people = (People) obj;
        if (name != null ? !name.equals(people.name) : people.name != null) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }

    public static void main(String[] args) {
        Map<People, Integer> map = new HashMap<People, Integer>();
        map.put(new People("icharle"), 18);

        System.out.println(map.get(new People("icharle")));
    }
}
# 输出结果为18

原因分析

HashMap在查找某一个key时,先是用hashCode函数根据该key的地址计算,再用equals函数根据对象的地址进行比较。

  • 在代码片段一中,map.put(new People("icharle"), 18);以及System.out.println(map.get(new People("icharle")));中默认是两个对象(也就是说两个对象的地址不一样,自然hashcode函数得到的值是不一样(因为两个的对象的地址不同,自然在equals时候更不可能相等,最终得到的结果为null
  • 在代码片段二中,重载hashCode()函数的作用是:对于同一个key,得到相同的hash值,重载equals()函数的作用是:向HashMap表明当前对象和key上所保存的对象是相等的。因此该情况下最终结果为18
标签: Java
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码
添加新评论