我正在学习Java HashMapClass(Key,Value),并发现为什么Key需要将Immutable它添加到hash之后稍后更改它可能在错误的桶中.
但那怎么样Value?它需要Immutable也是吗?
这来找我,因为我最近遇到一个问题,我有怪异的行为(即没有在地图上的键返回真containsKey()当我使用),AtomicInteger用addAndGet()方法更改值.
然后,new Integer()每当我需要更改与键对应的值并解决问题时,我就切换到put .
编辑
那么这只是要求Immutable,但这里是代码:
`
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());
}
Run Code Online (Sandbox Code Playgroud)
问题是******在count_temp中打印了手机(即我得到了null).当我插入AtomicInteger手机时我可以这样做然后我查了一下,发现手机从未插入哈希地图并且仍然containsKey()返回这是真的.
现在任何人都可以解释为什么会发生这种情况以及为什么要更改Integer()并插入new Integer(changed value)更正它?
可以修改地图的价值.
还可以修改密钥.关键需要遵循的条件equals()和hashCode()之前和修改之后将给出(在的情况下,用相同的输入值相同的结果equals()).此外,如果可以修改密钥,通常它们是不可修改的.
为了更好地说明密钥可以修改的原因,我添加了一些关于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
Run Code Online (Sandbox Code Playgroud)
这是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;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,首先计算hashCode出密钥.然后使用hashCode在表中查找索引.如果地图中存在a Key,则可以通过该位置的Entry元素的链接列表来循环.要检查该键是否存在,使用equals()方法(在for循环内).
如何构建可在地图中使用的可修改密钥
因此,假设您要使用以下类作为键.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
这个类是可以修改的.您可以根据需要更改属性的值modifiablePart.但它可以用作地图的关键因素,equals并且hashCode当modifiablePart改变值时不会改变它们的行为.