当哈希值发生变化时,Java HashSet元素不会自行重新排列

Ans*_*hul 0 java collections

import java.util.*;
class KeyMaster {
    public int i;
    public KeyMaster(int i) { this.i = i; }
    public boolean equals(Object o) { return i == ((KeyMaster)o).i; }
    public int hashCode() { return i; }
}

public class MapIt {
    public static void main(String[] args) {
            Set<KeyMaster> set = new HashSet<KeyMaster>();
        KeyMaster k1 = new KeyMaster(1);
        KeyMaster k2 = new KeyMaster(2);
        set.add(k1); set.add(k1);
        set.add(k2); set.add(k2);
        System.out.print(set.size() + “:”);
        k2.i = 1;
        System.out.print(set.size() + “:”);
            set.remove(k1);
        System.out.print(set.size() + “:”);
        set.remove(k2);
        System.out.print(set.size());
     }
  }
Run Code Online (Sandbox Code Playgroud)

结果是什么?

A. 4:4:2:2
C. 2:2:1:0
E. 2:1:0:0
G. 4:3:2:1
B. 4:4:3:2
D. 2:2:0:0
F. 2:2:1:1
Answer: F
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释答案.我怀疑是这样的.K2的我改变但是仍然有2个元素,其中一个我认为仍然是指被改变的k2引用的对象.那么为什么不删除(k2)有效?

ahj*_*ton 6

将值添加到集合时仅对值进行哈希处理,更改哈希值的结果不会导致值在集合中重新哈希.

因此,假设您的HashSet有两个存储桶,一个是哈希码为1,另一个是哈希码为2,当您添加它们时,k1将进入存储桶1,k2将进入存储桶2.

当您将k2s值更改为1时,它不会在HashSet中重新排列.

当您尝试删除k2时,由于i的值,它会对存储桶1进行哈希处理,因为存储桶中没有任何内容匹配(因为您已经删除了k1),所以没有删除任何内容.

如果删除了任何内容,HashSet #remove会返回一个布尔值; 如果你打印,你会发现你没有发现你的k2被删除.