hashMap键值类型

可变对象:指创建后自身的哈希值可能被改变的对象。

hashMap储存键值对方式

插入

HashMap用Key的哈希值来存储和查找键值对。当插入一个value时,HashMap会计算Key的哈希值然后把value和这个哈希值相关联。

查找

HashMap通过计算Key的哈希值查找相关联的value。

问题

如果key的类型是一个可变对象那就会出现问题,比如以下代码

public static void main(String[] args) {
		Map<User,Integer>map=new HashMap<>();
        User user=new User(1);
        System.out.println("初始hash:"+user.hashCode());
        map.put(user,11);
        user.setName("11");
        System.out.println("赋值后的hash:"+user.hashCode());
        System.out.println(map.get(user));
}
class User {
    private int id;
    private String name;
    
	public User(final int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

运行结果:

初始hash:3524
赋值后的hash:5049
null

这里的user是可变对象。当改变user的属性时其hash值发生了变化,map中是查找不到对应的值的

解决方法

改变可变对象的hash方法,通过改变user的hash方法使其name不参与hash计算,并使其创建后无法改变id即可

		Map<User,Integer>map=new HashMap<>();
        User user=new User(1);
        System.out.println("初始hash:"+user.hashCode());
        map.put(user,11);
        user.setName("11");
        System.out.println("赋值后的hash:"+user.hashCode());
        System.out.println(map.get(user));
}
class User {
    private int id;
    private String name;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return id == user.id &&
                Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {

        return Objects.hash(id);
    }

    public User(final int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

运行结果:

初始hash:32
赋值后的hash:32
11
发布了92 篇原创文章 · 获赞 4 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/DingKG/article/details/103171513
今日推荐