使用双键创建hashmap

时间:2011-12-21 14:13:04

标签: java data-structures hashmap key

我正在为我的问题寻找合适的数据结构。我希望能够使用两个键尽可能高效地选择节点对象。插入和删除也需要有效。基本上每个节点对象都有一对两个键。这些对是唯一的,但个别键不是。我需要能够为两个密钥之一选择一组具有特定值的节点。

示例:

Node1有键a1和b1

Node2有键a1和b2

Node3有键a2和b2

我想例如能够选择具有密钥a1,b1的节点以及具有b2作为key2的所有节点。

我当然可以制作两个HashMaps(每个键一个),但这是一个丑陋的解决方案,因为当我添加或删除某些内容时,我必须在两个地图中执行此操作。由于会有很多添加和删除,我宁愿一次性完成。有没有人对如何做到这一点有任何想法?

显然,只有一个键将两个键合并在一起并不能解决问题,因为我还需要能够搜索单个键而无需搜索整个地图。那不会很有效率。问题是效率问题。我可以在地图中搜索特定键的每个条目,但我想使用哈希,以便我可以立即使用两个键中的任何一个选择多个节点对象。

我不是在寻找类似MultiKeyMap的东西,因为在这个数据结构中第一个键总是保持不变,你只能添加键而不是用不同的键替换第一个键。我希望能够在第一个和第二个键之间切换。

我确实并且不希望使用相同的密钥存储多个对象。如果您查看示例,您可以看到两个键一起始终是唯一的。这可以看作是单个键,因此我不会在同一个键下存储多个对象。但是如果你看一下各个键,它们并不是唯一的,因此我想存储各个键所引用的多个对象。

7 个答案:

答案 0 :(得分:6)

如果您可以使用库,请查看Guava的Table界面。它将行和列与值相关联。行和列可能是您的第一个和第二个键。您也可以按行或按列进行搜索。

此界面的一个实现是hash based

答案 1 :(得分:5)

您必须创建一个密钥类(相等性被视为Point):

public class Key {

    int field1;
    int field2;

    public boolean equals(Object o) {
        if (o == null || !(o instanceof Key)) return false;
        Key other = (Key) o;
        return field1 == other.field1 && field2 == other.field2;
    }

    public int hashCode() {
        return field1*field2; // doesn't matter if some keys have same hash code
    }

}

用于在第一个字段中选择具有一个特定值的键:

public List<Key> getKeysWithField1EqualsTo(int value) {
    List<Key> result = new ArrayList<>();
    for (Key k: map.keySet()) {
        if (k.field1 == value) result.add(k);
    }
    return result;
}

答案 2 :(得分:2)

由于这对您手头的问题非常具体,因此您很可能需要开发自己的集合。我会从Apache Commons中将两个MultiMaps包装到我自己的集合类中,该集合类同时处理两个多映射的更新,并使用我的类来执行插入和查询。

答案 3 :(得分:1)

编写一个能够包含两个值(键)的简单类,并覆盖equals(..)和hashCode()以进行映射使用的相等性检查。使用这个简单的类作为地图的关键。

在这里你可以找到一个与hashmap兼容的对类(第二个答案):

What is the equivalent of the C++ Pair<L,R> in Java?

答案 4 :(得分:1)

由于HashMap只能为每个对象分配一个哈希值,因此您永远无法选择开箱即用的不同列表。我建议使用带有两个键的元组,然后遍历HashMap并仅选择那些具有tuple.key1 = X的元素。

答案 5 :(得分:1)

HashMaps可以将任何对象作为Key,因此为什么不创建一个包含2个字段的类,并将此类视为您的密钥。你也可以覆盖Equals方法告诉它键是等于

答案 6 :(得分:0)

我认为我们可以这样做:对于每个键,我们可以计算相应的哈希码。

key1 -> hashcode1
key2 -> hashcode2

然后我们有一个二维数组,有N列和N行。

key1 -> rowIndex: hashcode1 MOD N
key2 -> columnIndex: hashcode2 MOD N

然后我们将项目存储在array[rowIndex][columnIndex]中。

在此实现中,您可以使用目标key1和任何key2获取所有条目。您还可以使用目标key2和任何key1获取所有条目。

当存在大量冲突时,此数组可能会扩展,就像您对普通hashmap所做的那样。