Java HashMap是否要求值不可变?

Java HashMap是否要求值不可变?,java,hashmap,Java,Hashmap,我正在学习JavaHashMap类(键,值),并发现为什么Key需要是不可变的,就好像它被添加到散列后被更改了一样,它可能位于错误的桶中 但是关于值呢?它也需要是不可变的吗 我最近遇到了一个问题,当我使用AtomicInteger和addAndGet()方法更改值时,我出现了奇怪的行为(映射中不存在的键在containsKey()上返回true) 然后,每当我需要更改键对应的值时,我就切换到放置newinteger(),这就解决了问题 编辑 这只是要求不可变的,但代码如下: ` HashMap

我正在学习Java
HashMap
类(键,值),并发现为什么
Key
需要是
不可变的
,就好像它被添加到散列后被更改了一样,它可能位于错误的桶中

但是关于
呢?它也需要是不可变的吗

我最近遇到了一个问题,当我使用
AtomicInteger
addAndGet()
方法更改值时,我出现了奇怪的行为(映射中不存在的键在
containsKey()
上返回true)

然后,每当我需要更改键对应的值时,我就切换到放置
newinteger()
,这就解决了问题

编辑

这只是要求不可变的,但代码如下:

`

HashMap hash_map=newhashmap();
HashMap hash_map_count=新HashMap();
//这里有一些代码,让我们假设phone值出现在函数中,而函数包含此代码
if(hash_map.containsKey(phone))//存在
{
ps_insert=(PreparedStatement)hash_map.get(phone);
count\u temp=hash\u map\u count.get(电话);
如果(计数温度==null)
{
System.out.println(“*************”+电话);
}
count_temp.addAndGet(1);//无需在此处将值更改为+1时重新插入到映射中。
System.out.println(“count:+count_temp.get());//
}
其他的
{
ps_temp=conn.prepareStatement(“插入T_”+phone+“值(?,,,,,,,,,,?)”;
散列映射放置(电话、ps临时);
count_temp=新的原子整数(1);
hash\u map\u count.put(电话,count\u temp);
ps_插入=ps_温度;
System.out.println(“新电话:+phone+”计数:+count_temp.get());
}
问题是在count_temp中用phone打印了******(即我得到了null)。当我为phone插入了一个
AtomicInteger
时,这怎么可能呢 然后我检查并发现电话从未插入到哈希映射,仍然
containsKey()
为其返回true


现在,有人能解释为什么会发生这种情况,以及为什么更改为
Integer()
并插入
新的整数(更改的值)
纠正了它吗?

可以修改贴图的值

还可以修改密钥。密钥需要遵循这样的条件,即修改前后的
equals()
hashCode()
将给出相同的结果(如果是
equals()
,则输入值相同)。此外,如果密钥通常可以修改,则它们是不可修改的

为了更好地说明为什么键可以修改,我添加了一些关于HashMap如何工作以及如何对可修改键进行编码的解释

哈希映射的工作原理:

在内部,HashMap使用条目数组,其中条目是tern(键、值、条目)

下面是get()的代码


这个类是可修改的。您可以根据需要更改属性
modifiablePart
的值。但它也可以用作映射的键,实际上
等于
hashCode
不会在可修改部分更改值时更改其行为。

首先,在其他映射上调用containesKey,然后从另一个映射获取值。这就是为什么你会得到不同的结果

if(hash_map.containsKey( phone))
   count_temp = hash_map_count.get( phone);
        if(count_temp == null)
其次,值在HashMap中不需要是不可变的。但密钥必须是不变的。然而,map不会对其强制任何规则,但如果key不是不可变的,那么您可能会在map中看到意外的行为。只有在确保hashcode()和equals()中使用的key类中的实例属性在初始化后从未更改的情况下,map中才能有可变键。 有关更多详细信息,请参阅下面的博客。

请显示导致问题的特定代码。值不必是不可变的。因此,没有要求
也需要与
@Eran一起不可变,我当时的意思是
。我还在等着看引起问题的代码,就像Eran最初问的那样。可能是重复的。你能再澄清一下最后一句话吗?我认为目前很难理解这是什么意思(我可以做出一个很有根据的猜测,在这种情况下,这是有意义的,但这不应该是必要的)。
table

0 --> {K, V, E} --> {K, V, null}
1 --> {k, V, null}
2
3
4 --> {K, V, null}
5
 public V get(Object key) {
     if (key == null)
        return getForNullKey();
     int hash = hash(key.hashCode());
     for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
         Object k;
         if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
             return e.value;
     }
     return null;
 }
public class ModifiableKey {
    private String unmodifiablePart;
    private String modifiablePart;


    public ModifiableKey(String unmodifiablePart) {
        this.unmodifiablePart = unmodifiablePart;
    }

    public String getUnmodifiablePart() {
        return unmodifiablePart;
    }

    public boolean equals(Object obj) {
        ModifiableKey mk = (ModifiableKey) obj;
        return unmodifiablePart.equals(mk.getUnmodifiablePart());
    }

    public int hashCode() {
        return unmodifiablePart.hashCode();
    }

    public void setModifiablePart(String modifiablePart) {
        this.modifiablePart = modifiablePart;
    }

    public String getModifiablePart() {
        return modifiablePart;
    }
}
if(hash_map.containsKey( phone))
   count_temp = hash_map_count.get( phone);
        if(count_temp == null)