2012-07-01 39 views
1

我是新来的java。 我有以下有复合键数据库表:Java收集和MapKey

Code 
Reference_Number_1 (decimal) 
Reference_Number_2 (decimal) 
Time 

以上按键使各行的唯一行 - 没有dupliactes。 我需要创建一个类来将这个表加载到一个java集合中,并创建一个静态方法,它将以上面四个参数作为关键字并从java集合中返回实体。

我想将表加载到HashMap中,但我不知道如何定义MapKey。我应该将Reference_Number_1,Reference_Number_2和Time in转换为字符串,然后连接这四个字段? 或者有另一种方法/集合来加载这个表。 谢谢, 皮特

+1

为什么不直接将键与'+'符号连接起来,并将其用作hashmap的键,其余部分是与键关联的数据。这是最简单的解决方案 - 你真的需要更复杂的东西吗? – PhD

+0

嗨,感谢您的快速响应。是的,这是最简单的方法,但我不确定是否可以将String,decimal和Time组合为生成MapKey作为String。当然,会这样做。谢谢你的帮助。彼得 – Peter

+3

要小心,这种技术充满了模糊性。考虑reference_number_1和reference_number_2及其各自级联的以下元组:(10,10)=“1010”和(101,0)=“1010”。假设这两个例子中的代码和时间都是相同的,则密钥会发生冲突,并且一个值会被覆盖。 – jkschneider

回答

6

创建另一个类持有这4个领域的性能和执行/自动生成equals()hashCode()according the contract(重要!否则就不能作为一个适当的Map键使用),并最终把它作为(复合)键为Map

这里是Eclipse已经自动生成的,我(的equals()是开放的改善,这是有点繁琐):

public class CompositeKey { 

    private String code; 
    private BigDecimal referenceNumber1; 
    private BigDecimal referenceNumber2; 
    private Date time; 

    public CompositeKey(String code, BigDecimal referenceNumber1, BigDecimal referenceNumber2, Date time) { 
     this.code = code; 
     this.referenceNumber1 = referenceNumber1; 
     this.referenceNumber2 = referenceNumber2; 
     this.time = time; 
    } 

    public String getCode() { 
     return code; 
    } 

    public BigDecimal getReferenceNumber1() { 
     return referenceNumber1; 
    } 

    public BigDecimal getReferenceNumber2() { 
     return referenceNumber2; 
    } 

    public Date getTime() { 
     return time; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     CompositeKey other = (CompositeKey) obj; 
     if (code == null) { 
      if (other.code != null) 
       return false; 
     } 
     else if (!code.equals(other.code)) 
      return false; 
     if (referenceNumber1 == null) { 
      if (other.referenceNumber1 != null) 
       return false; 
     } 
     else if (!referenceNumber1.equals(other.referenceNumber1)) 
      return false; 
     if (referenceNumber2 == null) { 
      if (other.referenceNumber2 != null) 
       return false; 
     } 
     else if (!referenceNumber2.equals(other.referenceNumber2)) 
      return false; 
     if (time == null) { 
      if (other.time != null) 
       return false; 
     } 
     else if (!time.equals(other.time)) 
      return false; 
     return true; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((code == null) ? 0 : code.hashCode()); 
     result = prime * result + ((referenceNumber1 == null) ? 0 : referenceNumber1.hashCode()); 
     result = prime * result + ((referenceNumber2 == null) ? 0 : referenceNumber2.hashCode()); 
     result = prime * result + ((time == null) ? 0 : time.hashCode()); 
     return result; 
    } 

} 
+0

谢谢。我想尝试两种方法,但想了解如果我连接这四个字段并为HashMap创建一个键或按照您的建议方式,有什么区别。 – Peter

+0

更好的抽象。 – BalusC

+0

更好的抽象,改进的可读性和可维护性。使用字符串是非常脆弱和不好的做法。 –

2

中的对象封装这四个领域:

public class Key { 
    String code; 
    float reference1; 
    float reference2; 
    Date time; 

    public Key(String code, float ref1, float ref2, Date time) { 
     ... 
    } 

    // implement equals() and hashCode() 
} 

然后定义一个Map如下(不知道什么类型的“实体”是,所以我们只会假装有一个类叫Entity

Map<Key, Entity> lookup = new HashMap<Key, Entity>();