这是我的一段代码:
public UserConnection getUserConnectionByToken(Token token) {
// TODO Auto-generated method stub
for (Iterator iter = (Iterator) TransactionManagerImpl.userConnections
.keySet().iterator(); iter.hasNext();) {
Token token1 = iter.next();
if(token1.equals(token)){
return userConnections.get(token1);
}
}
return (UserConnection)userConnections.get(token);
}
其中userConnections是一个ConcurrentHashMap,里面的key是Token对象,value是UserConnection 对象,这是webservice服务端的一个方法,token是在客户端传过来的,都实现了序列化,但是在服务端处理的时候,直接 userConnections.get(token)却取不出来,但是通过迭代判断if(token1.equals(token)){return userConnections.get(token1);}却能取出来,这是怎么回事儿呢,哪位帮解释一下?
你看看ConcurrentHashmap的get方法
[code="java"]
/* Specialized implementations of map methods */
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if ([color=red]e.hash == hash && key.equals(e.key[/color])) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
[/code]
看到红色部分么?你需要equals && == 你最好在hashcode相等的时候端点进去看看,是不是equals相等
map只是比较hashcode
但是equals 是 ==
所以出不来
反序列化不能保证hashcode一致,你必须得重写hashcode
[quote]已经重写了equals和hashCode,Token只有一个String的属性[/quote]
看看你是如何重写的?
我说错了,反序列化和hashcode无关,如果你重写了hashcode,可能有隐患
你的token不要重写hashcode,因为你如果都是一个object,但是因为string属性改变而使得hashcode改变,你的map就得不到,但是他们还是同样的object
最简单打印所有的hashcode
你看看value是什么指,跟踪进去看看他hashcode的方法
[quote]服务端的一个方法,token是在客户端传过来的,都实现了序列化[/quote]
这要在序列化之前就重写,序列化之后再重写就没意义了。
用默认的hashcode,一般来说没有多少问题,除非你有特殊的要求非要使用自定义hashcode
[quote]客户端打印的hashCode和服务端打印的hashCode值一样,但还是取不出来[/quote]
token1 和 token 的 hashCode 一样吗? 如果一样,肯定可以拿出来。