簡體   English   中英

轉換集<map.entry<k, v> &gt; 至 HashMap <k, v></k,></map.entry<k,>

[英]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可以直接在HashSetHashMap之間進行轉換,您需要遍歷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.entrySetMap備份。 請參閱下面的javadoc

Set<Entry<Integer, String>> java.util.Map.entrySet()

返回此映射中包含的映射的 Set 視圖。 該集合由地圖支持,因此對地圖的更改會反映在該集合中,反之亦然。 如果在對集合進行迭代時修改了映射(除了通過迭代器自己的刪除操作,或者通過迭代器返回的映射條目上的 setValue 操作),迭代的結果是未定義的。 該集合支持元素移除,通過 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作從映射中移除相應的映射。 它不支持 add 或 addAll 操作。

相當短的 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(Collectors.toMap(Entry::getKey,
      Entry::getValue,
      (a,b)->b));

編輯:感謝shmosel比我更值得稱贊

從番石榴 19 開始,您可以使用ImmutableMap.copyOf(Iterable<Map.Entry<K,V>>)

這些是常用庫中的一些toMap實用程序,但不幸的是,它們都不直接支持Set ,因此您需要先執行Set#toArray() (我在尼爾的回答中省略了番石榴,這可以說是最好的)

Commons Lang 的ArrayUtils.toMap

Map<Object, Object> map = ArrayUtils.toMap(entrySet.toArray());

// to recover the type...
@SuppressWarnings("unchecked")
Map<K, V> typedMap = (Map<K, V>)(Map<?, ?>)map;

Commons Collections 的MapUtils.putAll

Map<K, V> map = MapUtils.putAll(new HashMap<K, V>(), entrySet.toArray());

Java 9 的Map.ofEntries

 // 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+ 沒有抑制警告

從 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);

爪哇 8

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) 返回firstsecond取決於您是要保留為某個鍵找到的第一個值還是最新的值。

Map<Integer,String> map = set.stream().collect(Collectors.toMap(
        Entry::getKey, 
        Entry::getValue, 
        (first, second) -> first));   // or '-> second' if you need the latests

Java 7 及更早版本

您所能做的就是對每次迭代進行程序化,如現有答案所描述的那樣。

在 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.

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