gpt4 book ai didi

java - Java HashMap 是否要求值是不可变的?

转载 作者:行者123 更新时间:2023-11-30 06:13:54 25 4
gpt4 key购买 nike

我正在学习 Java HashMap Class(Key,Value) 并发现为什么 Key 需要是 Immutable 就好像它稍后会改变一样被添加到哈希中可能在错误的桶中。

但是 Value 呢?它是否也需要不可变

这是我最近遇到的一个问题,当我使用 AtomicIntegeraddAndGet() 方法改变值。

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

编辑

好吧,这只是要求不可变,但这是代码:

`

HashMap<Long , PreparedStatement> hash_map= new HashMap<Long, PreparedStatement>(); 
HashMap<Long , Integer> hash_map_count = new HashMap<Long , Integer>();

//some code here , lets say phone value comes to a function and function contains this code

if(hash_map.containsKey( phone)) // present
{
ps_insert = (PreparedStatement)hash_map.get( phone);
count_temp = hash_map_count.get( phone);

if(count_temp == null)
{
System.out.println("************"+ phone);

}

count_temp.addAndGet(1); //no need to re-insert into map as value changed by +1 here.
System.out.println("count : "+count_temp.get()); //

}
else
{
ps_temp = conn.prepareStatement("INSERT into T_"+ phone+" VALUES (?,?,?,?,?,?,?)");
hash_map.put( phone,ps_temp);
count_temp = new AtomicInteger(1);
hash_map_count.put( phone, count_temp);
ps_insert = ps_temp;
System.out.println("new phone :"+ phone+" count :"+count_temp.get());
}

问题是 ****** 在 count_temp 中用电话打印(即我得到空值)。当我为电话插入 AtomicInteger 时,这怎么可能然后我检查了一下,发现电话从未插入到 HashMap 中,而且 containsKey() 仍然返回 true。

现在有人可以解释为什么会发生这种情况以及为什么更改为 Integer() 并插入 new Integer(changed value) 可以更正它吗?

最佳答案

可以修改 Map 的值。

也可以修改 key 。 Key 需要遵循这样的条件,即修改前后的 equals()hashCode() 将给出相同的结果(在 equals 的情况下具有相同的输入值())。此外,如果 key 通常可以修改,则它们是不可修改的。

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

HashMap 的工作原理:

在内部,HashMap 使用一个 Entry 数组,其中 Entry 是一个 tern (Key, Value, Entry)。

table

0 --> {K, V, E} --> {K, V, null}
1 --> {k, V, null}
2
3
4 --> {K, V, null}
5

这里是get()的代码

 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;
}

如您所见,首先计算的是 key 的hashCode。然后使用 hashCode 在表中查找索引。如果 Key 存在于 map 中,则可以通过该位置的 Entry 元素的链表循环到达它。要检查该键是否存在,使用 equals() 方法(在 for 循环内)。

如何构建可在 map 中使用的可修改键

因此,假设您希望将以下类用作键。

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;
}
}

这个类是可修改的。您可以根据需要更改属性 modifiablePart 的值。但它也可以用作映射的键​​,事实上 equalshashCode 在 modifiablePart 更改值时不会改变它们的行为。

关于java - Java HashMap 是否要求值是不可变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31218031/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com