[英]Creating a hashmap with a double key
我正在為我的問題尋找合適的數據結構。 我希望能夠使用兩個鍵盡可能高效地選擇節點對象。 插入和刪除也需要有效。 基本上每個節點對象都有一對兩個鍵。 這些對是唯一的,但個別鍵不是。 我需要能夠為兩個鍵中的一個選擇一組具有特定值的節點。
例:
Node1具有鍵a1和b1
Node2具有密鑰a1和b2
Node3具有密鑰a2和b2
我想例如能夠選擇具有密鑰a1,b1的節點以及具有b2作為key2的所有節點。
我當然可以制作兩個HashMaps(每個鍵一個),但這是一種丑陋的解決方案,因為當我添加或刪除某些東西時,我必須在兩個映射中都這樣做。 由於會有很多添加和刪除,我寧願一次性完成。 有沒有人對如何做到這一點有任何想法?
顯然,將兩個密鑰合並在一起的單個密鑰並不能解決問題,因為我還需要能夠搜索單個密鑰而無需搜索整個映射。 那不會很有效率。 問題是效率問題。 我可以在地圖中搜索特定鍵的每個條目,但我想使用哈希,以便我可以立即使用兩個鍵中的任何一個選擇多個節點對象。
我不是在尋找類似MultiKeyMap的東西,因為在這個數據結構中第一個鍵總是保持不變,你只能添加鍵而不是用不同的鍵替換第一個鍵。 我希望能夠在第一個和第二個鍵之間切換。
我喜歡並且不想使用相同的密鑰存儲多個對象。 如果您查看示例,您可以看到兩個鍵一起始終是唯一的。 這可以看作是單個鍵,因此我不會在同一個鍵下存儲多個對象。 但是如果你看一下各個鍵,它們並不是唯一的,因此我想存儲各個鍵所引用的多個對象。
您必須創建一個密鑰類(相等性被視為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類(第二個答案):
由於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.