簡體   English   中英

使用雙鍵創建hashmap

[英]Creating a hashmap with a double key

我正在為我的問題尋找合適的數據結構。 我希望能夠使用兩個鍵盡可能高效地選擇節點對象。 插入和刪除也需要有效。 基本上每個節點對象都有一對兩個鍵。 這些對是唯一的,但個別鍵不是。 我需要能夠為兩個鍵中的一個選擇一組具有特定值的節點。

例:

Node1具有鍵a1和b1

Node2具有密鑰a1和b2

Node3具有密鑰a2和b2

我想例如能夠選擇具有密鑰a1,b1的節點以及具有b2作為key2的所有節點。

我當然可以制作兩個HashMaps(每個鍵一個),但這是一種丑陋的解決方案,因為當我添加或刪除某些東西時,我必須在兩個映射中都這樣做。 由於會有很多添加和刪除,我寧願一次性完成。 有沒有人對如何做到這一點有任何想法?

顯然,將兩個密鑰合並在一起的單個密鑰並不能解決問題,因為我還需要能夠搜索單個密鑰而無需搜索整個映射。 那不會很有效率。 問題是效率問題。 我可以在地圖中搜索特定鍵的每個條目,但我想使用哈希,以便我可以立即使用兩個鍵中的任何一個選擇多個節點對象。

我不是在尋找類似MultiKeyMap的東西,因為在這個數據結構中第一個鍵總是保持不變,你只能添加鍵而不是用不同的鍵替換第一個鍵。 我希望能夠在第一個和第二個鍵之間切換。

我喜歡並且不想使用相同的密鑰存儲多個對象。 如果您查看示例,您可以看到兩個鍵一起始終是唯一的。 這可以看作是單個鍵,因此我不會在同一個鍵下存儲多個對象。 但是如果你看一下各個鍵,它們並不是唯一的,因此我想存儲各個鍵所引用的多個對象。

如果您可以使用庫,請查看Guava的Table界面。 它將行和列與值相關聯。 行和列可能是您的第一個和第二個鍵。 您也可以按行或按列進行搜索。

該接口的一個實現是基於散列的

您必須創建一個密鑰類(相等性被視為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;
}

由於這對您手頭的問題非常具體,因此您很可能需要開發自己的集合。 我將兩個MultiMap從Apache Commons包裝到我自己的集合類中,同時處理兩個多映射的更新,並使用我的類來執行插入和查詢。

編寫一個簡單的類,它能夠包含兩個值(鍵)並覆蓋equals(..)和hashCode(),用於映射使用的相等性檢查。 使用這個簡單的類作為地圖的關鍵。

在這里你可以找到一個兼容的hashmap類(第二個答案):

Java中C ++ Pair <L,R>的等價物是什么?

由於HashMap只能為每個對象排序一個哈希值,因此您永遠無法選擇開箱即用的不同列表。 我建議使用帶有兩個鍵的元組,然后遍歷HashMap並僅選擇那些具有tuple.key1 = X的元素。

HashMaps可以將任何對象作為Key,因此為什么不創建一個包含2個字段的類,並將此類視為您的密鑰。 您還可以覆蓋Equals方法,告訴它鍵是如何等於的

我認為我們可以這樣做:對於每個鍵,我們可以計算相應的哈希碼。

key1 -> hashcode1
key2 -> hashcode2

然后我們有一個2維數組,N列和N行。

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

然后我們將項存儲在array[rowIndex][columnIndex]

在此實現中,您可以使用目標key1和任何key2獲取所有條目。 您還可以使用目標key2和任何key1獲取所有條目。

當存在大量沖突時,此數組可能會擴展,就像您使用普通hashmap一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM