[英]Efficient way invert to invert a hashmap with a small number of the keys mapping to same values
我有一個哈希圖,我知道有些鍵映射到相同的值。
這些鍵的數量非常小(小於6%),並且它們映射在2-4個值之間。
例如
Map<String, String> map = new HashMap<>();
map.put("codeA", "100");
map.put("codeB", "7");
map.put("codeC", "0012");
我需要從值到鍵創建此映射的逆,所以我這樣做了:
inverseMap = new HashMap<String, ArrayList<String>>();
for(Map.Entry<String, String> e:map.entrySet()) {
String code = e.getKey();
String val = e.getValue();
ArrayList<String> codesColliding = inverseMap.get(val);
if(codesColliding == null) {
codesColliding = new ArrayList<>(4);
inverseMap.put(val, codesColliding);
}
codesColliding.add(code);
}
這行得通,但我認為它不是最佳選擇,因為我使用的內存比絕大多數鍵所需的內存更多。
盡管從編碼角度來看它有效,但我想知道是否可以通過其他方式(通過其他數據結構)來實現這一點。
注意:我對純Java 7(無額外的庫)方法感興趣
如果逆映射的值需要能夠容納原始映射中的多個鍵,則相對於不需要這樣的情況,就無法避免一些開銷。 您當前的方法還不錯,但是如果原始地圖值的很小一部分被重復,並且沒有重復多次,那么對於您使用的列表的初始容量,我會更加怯st作為逆映射中的值。 為什么要預分配不止一個元素? 您幾乎不需要重新分配,但是當您這樣做時,列表將對您透明地進行處理。
也許最簡單的方法是創建一個包含兩個HashMap的類,一個用於非碰撞鍵,另一個用於碰撞鍵。 如果您以某種方式消除沖突的歧義(例如,您始終按字母順序選擇第一個),則可以將該邏輯添加到類中。 或者,如果您想返回ArrayLists,則可以將非沖突的字符串懶惰地包裝到ArrayList中。
這全都在於了解您要對地圖執行的操作。 如果您確信代碼可以處理String和ArrayList結果之間的歧義,甚至可以犧牲一些類型安全性。
我知道您在談論Map<String,String>
,但為清楚起見,讓我們將其概括為Map<K,V>
,從中您將在其中構建Map<V,Collection<K>>
。 添加另一個Map<V,K>
,也許將其uniqueInverseMap
。 掃描條目時,請始終先在inverseMap
檢查密鑰,然后再uniqueInverseMap
。 如果已經在uniqueInverseMap
,請將其刪除,創建一個新的兩元素列表,然后將該列表添加到inverseMap
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.