将Set <Map.Entry <K,V >>转换为HashMap <K,V>

Joe*_*dev 27 java map set

在我的代码中,我Set<Map.Entry<K, V>>从地图创建了一个.现在我想重新创建相同的地图表单,所以我想将其HashSet<Map.Entry<K, V>>转换为HashMap<K, V>.Java是否有本机调用,或者我是否必须遍历set元素并手动构建映射?

Tag*_*eev 43

更简单的Java-8解决方案涉及Collectors.toMap:

Map<Integer, String> mapFromSet = set.stream()
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

IllegalStateException如果遇到重复键,将抛出一个.


har*_*rsh 21

有没有在java中内置的API之间的直接转换HashSetHashMap,你需要通过设置迭代和使用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());
    }
Run Code Online (Sandbox Code Playgroud)

虽然这里的目的是什么,如果你做了任何改变,Set那也将反映在MapMap.entrySet备份所返回的集合中Map.见javadoc下文:

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

返回此映射中包含的映射的Set视图.该集由地图支持,因此对地图的更改将反映在集中,反之亦然.如果在对集合进行迭代时修改了映射(除非通过迭代器自己的remove操作,或者通过迭代器返回的映射条目上的setValue操作),迭代的结果是未定义的.该集支持元素删除,它通过Iterator.remove,Set.remove,removeAll,retainAll和clear操作从地图中删除相应的映射.它不支持add或addAll操作.


mik*_*lly 6

相当短的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));
Run Code Online (Sandbox Code Playgroud)

编辑:感谢shmosel应该得到比我更多的信誉

  • 你可以很容易地使用`Collectors.toMap(Entry :: getKey,Entry :: getValue,(a,b) - > b)`. (2认同)

sni*_*nip 5

截至 2018 年,toMapApache 库中有一些实用程序,但不幸的是它们都不Set直接支持,因此您需要Set#toArray()先这样做。

我把番石榴留给了尼尔的答案,这可以说是最好的。

Apache 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;
Run Code Online (Sandbox Code Playgroud)

Apache Commons Collections 的MapUtils.putAll

Map<K, V> map = MapUtils.putAll(new HashMap<K, V>(), entrySet.toArray());
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)


Nik*_*las 5

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"));
Run Code Online (Sandbox Code Playgroud)

请注意,该方法也Map.entry(K, V)可用,这使得一切变得不那么冗长。

Map<Integer,String> map2 = Map.ofEntries(
        Map.entry(1, "one"), 
        Map.entry(2, "two"), 
        Map.entry(3, "three"));
Run Code Online (Sandbox Code Playgroud)

假设您有Set<Map.Entry<K, V>>,您需要一个数组才能使用 using 方法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);
Run Code Online (Sandbox Code Playgroud)

爪哇8

Java 8 带来了 Stream API,使用Collectors.toMap(keyFn, valueFn).

Set<Map.Entry<Integer,String>> set = ...
Map<Integer,String> map = set.stream()
                             .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

为了避免出现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
Run Code Online (Sandbox Code Playgroud)

Java 7 及更早版本

您所能做的就是按照现有答案所述对每次迭代进行程序化。