可互换的键/值 HashMap Set 结构
背景
使用两个操作数创建一系列 SQL JOIN 语句:主操作数和辅助操作数。 JOIN 语句的一般形式为:
JOIN primary primary ON (secondary.id == primary.id)
问题
代码当前迭代主操作数和辅助操作数的列表,如下所示:
for( Bundle primaryOperand : bundleComparators ) {
for( Bundle secondaryOperand : sortedBundles ) {
问题是嵌套循环生成以下内容:
JOIN primary primary ON (secondary.id == primary.id)
JOIN secondary secondary ON (primary.id == secondary.id)
第二个连接是多余的,在本例中,会导致错误。可以使用以下假设的数据结构消除重复:
if( !interchangeableMap.contains( primaryOperand, secondaryOperand ) ) {
interchangeableMap.put( primaryOperand, secondaryOperand );
outputJoin( primaryOperand, secondaryOperand );
}
其中,如果 primaryOperand
映射到,则 interchangeableMap.contains(...)
将返回 true secondaryOperand
或 secondaryOperand
映射到primaryOperand
。
问题
- Java 库中是否存在这样的数据结构?
- 如果没有,您将使用什么数据结构来实现?
想法
我的第一个想法是创建一个包含两个 HashMap 的类。检查包含性时会查询两个 HashMap
,以查看一个映射是否包含主要和次要操作数,或者另一个映射是否包含次要和主要操作数。插入将两个操作数组合放入各自的 HashMap 中。
谢谢你!
Background
Create a series of SQL JOIN statements using two operands: primary and secondary. The generic form of the JOIN statement is:
JOIN primary primary ON (secondary.id == primary.id)
Problem
The code currently iterates over a list of primary and secondary operands, as follows:
for( Bundle primaryOperand : bundleComparators ) {
for( Bundle secondaryOperand : sortedBundles ) {
The problem is that the nested loop generates the following:
JOIN primary primary ON (secondary.id == primary.id)
JOIN secondary secondary ON (primary.id == secondary.id)
The second join is superfluous and, in this case, causes an error. The duplication can be eliminated with the following hypothetical data structure:
if( !interchangeableMap.contains( primaryOperand, secondaryOperand ) ) {
interchangeableMap.put( primaryOperand, secondaryOperand );
outputJoin( primaryOperand, secondaryOperand );
}
Where interchangeableMap.contains(...)
will return true if primaryOperand
is mapped to secondaryOperand
or secondaryOperand
is mapped to primaryOperand
.
Questions
- Does such a data structure exist in the Java libraries?
- If not, what data structures would you use for its implementation?
Ideas
My first thought is to create a class that contains two HashMap
s. Checking for containment queries the two HashMap
s to see if one map contains the primary and secondary operands or the other map contains the secondary and primary operands. Insertions put the two operand combinations into their respective HashMap
s.
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是基于 @roland 建议的解决方案:
然后:
该解决方案的一个微妙之处:您还必须重写
hashCode()
方法(哈希值必须反映等式关系),但必须采用对称的方式,即:的哈希值必须与
的哈希值 == 。
Here is a solution based on @roland's suggestion:
Then:
A subtle point about the solution: you must also override the
hashCode()
method (hash value must reflect the equality relation), but you must do it in a symmetric way, that is: the hash value of<a,b>
must be == to that of<b,a>
另一个想法是定义一个新的类
OperatorPair
,它重写equals()
并使用其中的Set
,再次使用进行检查>包含()
。但你的解决方案也应该运作良好。(另外,如果你这样做,你也应该覆盖
hashCode()
,例如你可以根据操作数的名称来计算它......参见例如 这个问题了解详细信息。)Another idea would be to define a new Class
OperatorPair
that overridesequals()
and use aSet
of those, again to be checked withcontains()
. But your solution should work well, too.(Also, if you do this, you should override
hashCode()
as well, for example you could calculate it based on the names of the operands... see e.g. this question for details.)我希望我没有完全错:
您可以使用
HashMap
并将每个映射放置两次:(primary, secondary)
和( secondary,primary)
。对于查找,您不会检查contains
,而是检查(get(primary) == secondary) 或 (get(secondary) == Primary)
。apache commons 库包含 BidiMap它允许“键和值之间的双向查找”。所以你也使用这个,以避免双重插入
I hope I'm not completely wrong:
You can use a
HashMap
and put each mapping twice:(primary, secondary)
and(secondary, primary)
. For a lookup you would not check forcontains
but(get(primary) == seconday) or (get(secondary) == primary)
.The apache commons library contains the BidiMap which allows a "bidirectional lookup between key and values". So you use this one too, to avoid the double insert