[英]Combining remove and put method in LinkedHashMap
使用LinkedHashMap ,當我嘗試重新插入具有不同值的相同鍵時,它會替換該值並保持鍵的順序,即如果我這樣做
Map<String,String> map = new LinkedHashMap<>();
map.put("a", "a");
map.put("b", "b");
map.put("c", "c");
map.put("d", "d");
map.values().stream().forEach(System.out::print);
輸出: abcd
現在,如果我在地圖中添加具有相同鍵的不同值,則順序保持不變,即
map.put("b", "j");
map.values().stream().forEach(System.out::print);
輸出: ajcd
有沒有其他辦法? 一種是刪除並重新插入具有新值的密鑰,將acdj
作為輸出打印。 在我的情況下,我想根據用作值的對象的某些屬性為多個鍵執行此操作?
使用流的解決方案將是可取的。
此鏈接列表定義迭代排序,通常是鍵插入映射的順序(插入順序)。 請注意,如果將鍵重新插入地圖,則插入順序不會受到影響
它跟蹤密鑰插入,如果我們添加Map.put
javadoc:
如果映射先前包含鍵的映射,則舊值將替換為指定的值。
Entry
不是替換,只修改了值,因此key
保持不變。
您需要刪除然后插入值以更新密鑰的順序。
HashMap不按鍵或值排序。 您正在尋找的是TreeMap。 對於HashMap,唯一的保證是,根據哈希值對密鑰進行哈希處理並放入數組中。
根據Javadoc,LinkedHashMap創建一個內部LinkedList,並跟蹤條目的原始插入順序。 換句話說,如果您使用LinkedHashMap,則根本不需要接收“排序”列表。
您有兩個選項可以解決此問題:使用TreeMap(或其派生),或每次排序,您想要輸出值。 TreeMaps根據其鍵進行內部排序。 如果按照您期望的方式將鍵進行比較(通過比較字符串),那么您將根據鍵獲得正確的升序排序。 但是,這並不能解決您的問題,您希望對值進行排序。
要解決原始問題,請使用雙向TreeMap。 Apache Commons4實現了這樣的地圖( https://commons.apache.org/proper/commons-collections/javadocs/api-4.3/org/apache/commons/collections4/bidimap/AbstractDualBidiMap.html#values-- )它允許你訪問鍵和值集。 但請注意,如果您的值不是唯一的,則此地圖不適合您 。 與鍵一樣,雙向映射中的所有值都必須是唯一的,因為它們本身需要用作鍵。
來自Javadoc:
此映射強制執行鍵和值之間存在1:1關系的限制,這意味着多個鍵無法映射到相同的值。 這是必需的,以便“反轉”地圖導致沒有重復鍵的地圖。 有關更多信息,請參閱put(K,V)方法說明。
如果我理解正確,您希望重新映射值等於已定義屬性的所有鍵值對,例如“a”,並使用流執行此操作。
這是一個解決方案。 首先選擇符合條件的所有地圖條目,然后為每個條目刪除並重新插入條目到地圖中。
String criterion = "a"; // For example
map.entrySet().stream()
.filter(e -> e.getValue().equals(criterion))
.collect(Collectors.toList())
.forEach(e -> { map.remove(e.getKey()); map.put(e.getKey(), e.getValue()); } );
例如,如果你有:
a=a
b=b
c=c
d=d
e=a
你會得到:
b=b
c=c
d=d
a=a
e=a
Hashmap插入僅基於哈希碼。 例如,“b”的鍵具有作為98的哈希碼。
對於map.put(“b”,“b”);
你插入一個鍵“b”,它有代碼98.所以它看起來像。 98 --->保持值'b'。
再次,如果你試圖把相同的鍵“b”只有一個哈希碼98。 所以hashmap嘗試僅在相同的哈希碼上鏈接,即98 --->將“j”作為值。
知道hashmap hashcode的工作請查看以下鏈接https://www.geeksforgeeks.org/internal-working-of-hashmap-java/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.