带有2个密钥的Java Collection

时间:2011-02-14 06:26:35

标签: java collections implementation

我想用一个带有2个组件的键来实现HashMap。实施例

Pseudocode:

Key = <Component1, Component2>
CollName<Key, Val> coll = new CollName<Key, Val>;

考虑到Collection的速度和大小,我如何在Java中实现它。谢谢:D

5 个答案:

答案 0 :(得分:7)

您需要一个包含两个键的辅助(复合键)类

public class CompositeKey<... , ...> {
   ... component1;
   ... component2;

   // getter , setter, ...

   // equals

  // hashcode()
}

然后你可以用它作为键:

CompositeKey cKey = new CompositeKey(1,2);
Map x.put(cKey,val);

这里以良好的方式实施equals()hashCode()非常重要。大多数IDE可以在这里为您提供帮助。重要的是,hashCode返回“唯一”值以防止密钥的哈希冲突(即返回常量值是最坏的情况,因为所有值都将在同一个桶中结束)。许多哈希码的实现都在做什么

hashcode = component1.hashCode() + 37* component2.hashCode();

如果您需要更多详细信息,请挖掘出任何讨论散列算法的CS书。

如果您想将其用于持久性,请查看this blog post

答案 1 :(得分:2)

您不能直接使用两个键创建Map,但是您可以将两者结合起来。

最简单的方法是将它们序列化为字符串并将它们组合起来。

String key = obj1.toString() + "-" + obj2.toString();
myMap.put( key, myValue );

假设对象可以很容易地序列化为唯一的字符串。

如果不是这种情况,那么创建包装器对象是最佳选择。您需要定义一个覆盖equals()和hashCode()方法的对象。

粗略的例子

class CombinedKey{
    private MyClass object1; 
    private MyClass object2;

    public CombinedKey( MyClass object1, MyClass object2 ){
        this.object1 = object1;
        this.object2 = object2;
    }
    public int hashCode(){ 
        return object1.hashCode() + object2.hashCode();
    }

    @Override
    public Boolean equals( Object otherObject ){
        if( otherObject == null || otherObject.getObject1() == null ) return false;
        return object1.equals( otherObject.getObject1() ) && object2.equals( otherObject.getObject2();
    }

    public MyClass getObject1() { return object1; }
    public MyClass getObject2() { return object2; }

}

(您可能还需要考虑使用泛型来定义此类,以便在其他方案中重用它)

用法:

Map<CombinedKey, Object> myMap = new HashMap<CombinedKey, Object>();
myMap.put( new CombinedKey(obj1, obj2), value );

答案 2 :(得分:1)

还没有看到Google Guava的答案,所以我想我会指出:我会使用Table

答案 3 :(得分:0)

这是HashMap的常见用法,关键是你必须在类{{1}中定义(覆盖) equals() hashCode()正确。

答案 4 :(得分:0)

使用CompositKey / Pair / Tuple的一个不错的选择是使用ListList个实施已经有一个正确定义的equals()hashCode(),并且可以使用Arrays.asList()轻松创建