有什么解决方案可以避免在两个键映射到相同值的情况下避免使用两个映射?问题:我们有一台服务器,它接收两种类型的请求-getDataByUserID(UserID userId)
和getDataByNodeID(NodeID nodeId)
,其中userId
和nodeId
具有一对一的映射。没有使用DB,所有数据都存储在内存中。有一个简单的解决方案-使用两个映射oneUserID/data
和second NodeID/data
,但是我想避免对两个表进行操作。服务器接口是:
void put (InetSocketAddress nodeId, String clientId, Data data);
Data get (InetSocketAddress nodeId);
Data get (String clientId);
欢迎任何建议。
没有智能数据结构可以执行此操作。正如@JavaMan所建议的,HashMap
如果键具有相同的超类型,则可以对两种类型的键都使用一个。但是,如果您需要并发解决方案,那么在没有竞争条件的情况下很难实现这一点。(您不能自动添加或删除两个条目...)
有一个讨厌的解决方案可以避免这种情况。您可以重新定义NodeId
andUserId
类,以实现一个通用接口;说CommonId
。然后,您需要重新定义equals(Object)
和hashCode()
方法,以便它们将两种标识符视为等效。
例如:
UserId a = ...
NodeId b = ... // representing the same user as 'a'
然后
a.equals(b) => true
b.equals(a) => true
a.hashCode() == b.hashCode()
除了equals / hashcode合约的其他方面。
重要说明:假设存在一种有效的方法来实现上述语义,而该语义不依赖于我们定义的映射。
然后,您可以将地图更改为HashMap<CommonId, YourValueClass>
,put
并get
使用UserId
实例或NodeId
实例作为键。
为什么这么讨厌?
因为此重新定义equals
并hashCode
适用于这两个类的所有用途,而不仅仅是此映射。
因为它违反了记录的语义equals(Object)
。javadocs说this.equals(other)
应该返回false
ifthis
和other
具有不同的类。
但是,这确实建议了一些替代解决方案:
您可以使用TreeMap
代替HashMap
,并提供Comparator<CommonId>
提供一致顺序的,并且将两种类型的等效标识符视为相等。
O(logN)
而非O(1)
forget
和put
操作。您可以尝试找到第3方哈希映射实现,该实现允许您提供哈希和等于函数。即类似于向aComparator
提供TreeMap
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句