【发布时间】:2011-10-23 20:31:07
【问题描述】:
我不确定在 Maps 中使用动态对象(例如 Set)作为键的主流观点是什么。
我知道典型的 Map 实现(例如,HashMap)使用哈希码来决定将条目放入哪个存储桶,并且如果该哈希码应该以某种方式改变(也许是因为 Set 的内容应该完全改变,那么这可能会导致桶被错误地计算(与 Set 最初插入 HashMap 的方式相比),从而弄乱 HashMap。
但是,如果我确保 Set 内容根本不改变,这是否是一个可行的选择?即便如此,由于 Set 固有的易变性质,这种方法是否通常被认为容易出错(即使采取了预防措施以确保它们不被修改)?
看起来 Java 允许将函数参数指定为 final;这也许是可以采取的一项小预防措施?
人们甚至在商业/开源实践中做这样的事情吗? (把 List、Set、Map 等作为 Maps 中的键?)
我想我应该描述一下我想用这个来完成什么,这样动机就会变得更加清晰,也许可以建议替代实现。
我想要完成的是拥有这样的东西:
class TaggedMap<T, V> {
Map<Set<T>, V> _map;
Map<T, Set<Set<T>>> _keys;
}
...本质上,能够用某些键(T)“标记”某些数据(V)并编写其他辅助功能来访问/修改数据并用它做其他花哨的事情(即返回一个列表满足某些键标准的所有条目)。 _keys 的作用是作为一种索引,方便查找值,而不必循环遍历 _map 的所有条目。
就我而言,我打算专门使用 T = String,V = Integer。我与之交谈过的人建议用字符串代替 Set,即:
class TaggedMap<V> {
Map<String, V> _map;
Map<T, Set<String>> _keys;
}
其中 _map 中的键属于“key1;key2;key3”类型,键由分隔符分隔。但我想知道我是否可以完成一个更通用的版本,而不必强制在键之间使用分隔符的字符串。
我想知道的另一件事是是否有某种方法可以将其作为地图扩展。我的设想是:
class TaggedMap<Set<T>, V> implements Map<Set<T>, V> {
Map<Set<T>, V> _map;
Map<T, Set<Set<T>>> _keys;
}
但是,我无法编译它,这可能是由于我对泛型的理解不足。以此为目标,任何人都可以修复上述声明,使其按照我所描述的精神工作,或建议一些轻微的结构修改吗?特别想知道“implements Map, V>”子句,是否可以声明这么复杂的接口实现。
【问题讨论】:
-
如果您将类型更改为:
class TaggedMap<T, V> implements Map<Set<T>, V>,您的最后一个 sn-p 就可以了。