背景
使用两个操作数创建一系列sql JOIN语句:primary和secondary. 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映射到secondaryOperand或将secondaryOperand映射到primaryOperand,则interchangeableMap.contains(…)将返回true.
问题
> Java库中是否存在这样的数据结构?
>如果没有,您将使用哪些数据结构来实现它?
思路
我的第一个想法是创建一个包含两个HashMaps的类.检查包含查询两个HashMaps以查看一个映射是否包含主操作数和辅助操作数,或者另一个映射包含辅助操作数和主操作数.插入将两个操作数组合放入它们各自的HashMaps中.
谢谢!
解决方法
这是基于@ roland建议的解决方案:
public final class Pair { private final Object a; private final Object b; public Pair(Object a,Object b) { this.a = a; this.b = b; } @Override public boolean equals(Object o) { if(o == null || !(o instanceof Pair)) return false; Pair that = (Pair) o; return this.a.equals(that.a) && this.b.equals(that.b) || this.a.equals(that.b) && this.b.equals(that.a); } @Override public int hashCode() { return a.hashCode() ^ b.hashCode(); } }
然后:
Set<Pair> set = new HashSet<Pair>(); for(Bundle primaryOperand : bundleComparators) { for(Bundle secondaryOperand : sortedBundles) { Pair p = new Pair(primaryOperand.id,secondaryOperand.id); if(set.contains(p)) continue; set.add(p); outputJoin(primaryOperand,secondaryOperand); } }
关于解决方案的一个细微之处:您还必须覆盖hashCode()方法(哈希值必须反映相等关系),但您必须以对称方式执行,即:< a,b>的哈希值.必须==与< b,a>