可更换的键/值的HashMap集结构HashMap

2023-09-11 04:34:34 作者:真的不快乐

创建一系列SQL JOIN使用两个操作数的语句:原发性和继发性。在JOIN语句的一般形式是:

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)

问题

在code当前迭代小学和中学的操作数的名单,具体如下:

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 );
}

其中, interchangeableMap.contains(...)返回真正如果 primaryOperand 被映射到 secondaryOperand 的或的 secondaryOperand 映射到 primaryOperand

Where interchangeableMap.contains(...) will return true if primaryOperand is mapped to secondaryOperand or secondaryOperand is mapped to primaryOperand.

在做这样的数据结构存在于Java库? 如果没有,你可以使用它的实施有什么数据结构?

我首先想到的是要创建一个包含两个的HashMap s的类。检查遏制查询两个的HashMap s至查看是否有地图包含的主要和次要操作数或其它地图包含了中小学操作数。插入把这两个操作数组合到各自的的HashMap 秒。

Ideas

My first thought is to create a class that contains two HashMaps. Checking for containment queries the two HashMaps 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 HashMaps.

感谢您!

推荐答案

下面是基于@解决罗兰的建议:

Here is a solution based on @roland's suggestion:

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);
  }
}

有关解决方案的一个巧妙之处:你还必须重写散code()办法(散列值必须反映平等关系),但你必须做它在一个对称的方式,那就是:的哈希值&LT; A,B&GT; 必须==到了&LT; B,A&GT ;

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>