簡體   English   中英

高效的方法是使用少量映射到相同值的鍵來反轉哈希圖

[英]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.

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