我尝试使用this answer中描述的技术将一些类自动装配到地图上。以下是代码示例:
// How are the implementation classes stored inside the map described
@Component("mapperOne")
public class DataMapper extends AbstractMapper {
...
}
// The abstract class, implementing the interface
public abstract class AbstractMapper implements Mapper<T> {
...
}
// Where the bug is actually occuring
public class MapperFactory {
@Autowired
private Map<String, Mapper<T>> mapperMap;
public void getMapper(String mapper) {
...
Mapper<T> mapper = mapperMap.get(mapper);
...
}
}
我知道我有@Component
注释引用的6个映射器,但是在调试模式下显示的数据不准确:
size
为6,modCount
为6。head
引用列表的第一个映射器。table
仅显示6个中的3个值。 tail
甚至不在table
!keySet
正确显示了我地图的6个条目。此问题带来NullPointerException
因为我试图访问不在地图中的映射器(尽管出现在keySet
中)。我注意到Spring使用LinkedHashMap
自动装配这些字段,我不知道它是否有任何后果。
那里发生了什么?我弄不清楚。任何帮助将不胜感激。
谢谢。
修改
看起来像是哈希冲突,所以没有任何问题。如果hashcode%table.size落在2个键的相同索引上,则它们的值将最终位于同一个存储桶中。您在同一索引处获得了一种链接的条目列表。你确定你使用的密钥是对的吗?
我运行了以下代码段:
for (Map.Entry<String, Mapper<T>> entry : mapperMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.hashCode() % mapperMap.size());
}
这给了我以下结果:
firstKey : -1
secondKey : -5
thirdKey : 5
fourthKey : -1
fifthKey : 2
sixthKey : 0
所以我们只在一个索引上发生了碰撞(first
和fourth
)。一段时间后我又有了一次消失,所以现在我的地图只包含firstKey
和thirdKey
作为具体实现。