我计划使用一个地图,其中键是相当长的列表(~10/100k 的小元素):
Map<List<K>, V> myMap = new HashMap<List<K>, V>();
默认List::hashCode()
实现(在 AbstractList 中)在循环中使用所有列表元素的哈希码计算它的哈希码值。该List::equals()
方法还依次比较所有列表元素,并为第一个不同的元素返回 false。
这一切都是有道理的,除了列表哈希码值没有被缓存(JDK 6)因此每次都重新计算,这使得这种使用模式非常低效(地图经常依赖哈希码)。对于不同的元素而言,问题会更少,equals()
因为平均而言,第一个不同的项目的索引相当低,因此循环会提前中断(但必须比较相同列表的所有元素)。
我正在考虑用一个新的自定义类封装我的列表,KeyList
将哈希码值保存在缓存中以提高性能,但是:
- 这不是微不足道的,因为您必须处理同步问题并实现一些列表接口方法;
- 这是侵入性的,因为您必须在客户端代码中使用此装饰器;
- 这并不能解决
equals()
比较相同元素时的性能问题。
处理这种情况会有更好的主意吗?