[英]Convert Set<Map.Entry<K, V>> to HashMap<K, V>
在我的代碼中,我從 map 創建了一個Set<Map.Entry<K, V>>
。 現在我想重新創建相同的 map 表單,所以我想將HashSet<Map.Entry<K, V>>
轉換回HashMap<K, V>
。 Java 是否有執行此操作的本機調用,還是我必須循環設置元素並手動構建 map?
涉及Collectors.toMap
更簡單的 Java-8 解決方案:
Map<Integer, String> mapFromSet = set.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
如果遇到重復鍵,將拋出IllegalStateException
。
java中沒有內置的API可以直接在HashSet
和HashMap
之間進行轉換,您需要遍歷set並使用Entry
填充映射。
一種方法:
Map<Integer, String> map = new HashMap<Integer, String>();
//fill in map
Set<Entry<Integer, String>> set = map.entrySet();
Map<Integer, String> mapFromSet = new HashMap<Integer, String>();
for(Entry<Integer, String> entry : set)
{
mapFromSet.put(entry.getKey(), entry.getValue());
}
盡管這里的目的是什么,如果您對Set
進行任何更改,這些更改也會反映在Map
因為Map.entrySet
返回的Map.entrySet
是Map
備份。 請參閱下面的javadoc
:
Set<Entry<Integer, String>> java.util.Map.entrySet()
返回此映射中包含的映射的 Set 視圖。 該集合由地圖支持,因此對地圖的更改會反映在該集合中,反之亦然。 如果在對集合進行迭代時修改了映射(除了通過迭代器自己的刪除操作,或者通過迭代器返回的映射條目上的 setValue 操作),迭代的結果是未定義的。 該集合支持元素移除,通過 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作從映射中移除相應的映射。 它不支持 add 或 addAll 操作。
從番石榴 19 開始,您可以使用ImmutableMap.copyOf(Iterable<Map.Entry<K,V>>)
這些是常用庫中的一些toMap
實用程序,但不幸的是,它們都不直接支持Set
,因此您需要先執行Set#toArray()
。 (我在尼爾的回答中省略了番石榴,這可以說是最好的)
Map<Object, Object> map = ArrayUtils.toMap(entrySet.toArray());
// to recover the type...
@SuppressWarnings("unchecked")
Map<K, V> typedMap = (Map<K, V>)(Map<?, ?>)map;
Map<K, V> map = MapUtils.putAll(new HashMap<K, V>(), entrySet.toArray());
// convert to array and recover the type...
@SuppressWarnings("unchecked")
Map<K, V> map = Map.ofEntries(entrySet.toArray(new Map.Entry[0]));
// You need to copy again if you want a mutable one
Map<K, V> hashmap = new HashMap<>(map);
從 Java 9 版本開始,集合接口提供了一堆方便的靜態方法,允許您內聯做很多事情。 有一個使用靜態方法Map.ofEntries(Map.Entry... entries)
的內置解決方案,它創建一個不可變的映射。
Map<Integer,String> map = Map.ofEntries(
new SimpleEntry<>(1, "one"),
new SimpleEntry<>(2, "two"),
new SimpleEntry<>(3, "three"));
請注意, Map.entry(K, V)
方法也可用,這使一切變得不那么冗長。
Map<Integer,String> map2 = Map.ofEntries(
Map.entry(1, "one"),
Map.entry(2, "two"),
Map.entry(3, "three"));
假設您有Set<Map.Entry<K, V>>
,您需要一個數組才能使用使用Set#toArray(T[])
。 由於禁止創建通用數組,因此需要顯式轉換,這是此解決方案的唯一缺點。
Set<Map.Entry<Integer,String>> set = ...
Entry<Integer, String>[] entries = set.<Entry<Integer,String>>toArray(Entry[]::new);
Map<Integer,String> map = Map.ofEntries(entries);
Java 8 帶來了使用Collectors.toMap(keyFn, valueFn)
非常簡單的 Stream API。
Set<Map.Entry<Integer,String>> set = ...
Map<Integer,String> map = set.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
為了避免在字典中禁止使用相同鍵的兩個Map.Entry
出現錯誤行為,請使用Collectors.toMap(keyFn, valueFn, mergeFn)
。 返回first
或second
取決於您是要保留為某個鍵找到的第一個值還是最新的值。
Map<Integer,String> map = set.stream().collect(Collectors.toMap(
Entry::getKey,
Entry::getValue,
(first, second) -> first)); // or '-> second' if you need the latests
您所能做的就是對每次迭代進行程序化,如現有答案所描述的那樣。
在 Java 8 中使用正確的組合器
Map<Integer, String> map = new HashMap<>();
//fill in map
Set<Map.Entry<Integer, String>> set = map.entrySet();
Map<Integer, String> mapFromSet =set.stream().collect(HashMap::new,(t, u) -> t.put(u.getKey(), u.getValue()),
(Map mapToReturn, Map otherMap) ->
{
otherMap.entrySet().forEach((Map.Entry entry) -> {
mapToReturn.put(entry.getKey(),entry.getValue());
});
return mapToReturn;}););
我想試試這個練習題。 我的問題是我需要將兩個“地圖”轉換為“集合”,這樣我就可以使用集合附帶的數學運算,例如並集、交集和差異。 在學習“Map.Entry”時,我發現我可以將“Maps”轉換為“Sets”,根據需要執行數學運算。 但是,我仍然需要根據問題要求將返回值轉換回“映射”。 我發現如果您將對象類型轉換回原始變量,我可以做到這一點。 我的最終結果是一個“地圖”,其中僅包含兩個地圖的交集。
public static Map<String, Integer> intersect(Map<String, Integer> map_one, Map<String, Integer> map_two)
{
Set<Map.Entry<String, Integer>> set_one = map_one.entrySet(); //Map one now a set
Set<Map.Entry<String, Integer>> set_two = map_two.entrySet(); //Map two now a set
set_one.retainAll(set_two); //a math intersection operation set_one and set_two whose contents are the intersection of the two sets
Map<String, Integer> map_retur = new HashMap<>(); //instantiation of a new Map object
Iterator i = set_one.iterator(); //instantiation of an iterator
while(i.hasNext())
{
Map.Entry me = (Map.Entry)i.next(); // instantiation of Map.Entry as me and convert i into that Map.Entry
map_retur.put((String)me.getKey(), (Integer)me.getValue()); // store each key/value pair into the Map as required
}
return map_retur; // returned value is a map with only the intersections
}
謝謝參考: https://www.tutorialspoint.com/java/java_mapentry_interface.html關於如何在每個循環中進行迭代。 但是,它不包括我在這里展示的類型轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.