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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章