首页 > 解决方案 > 如何转换列表> 进入地图> 在java中

问题描述

考虑以下问题。我想将地图列表转换为地图。

输入

[ 
  {a=1, b=2}, 
  {a=3, d=4, e=5},
  {a=5,b=6,e=7}
]

输出

{
  a=[1,3,5], 
  b=[2,6], 
  d=[4], 
  e=[5,7]
}
  

我尝试了以下代码。

代码


static <K,V> Map<K,List<V>> getMapFromTheList(List<Map<K,V>> list)
    {
        return list.stream().flatMap(map -> map.entrySet().stream())
        .collect(Collectors.groupingBy(Map.Entry::getKey,Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
    }  

有没有更好的方法来做到这一点?更简单的方法还是更有效的方法?

标签: javaarraylistjava-8hashmap

解决方案


替代方案可能如下所示:

static <K,V> Map<K,List<V>> getMapFromTheListOld_1(List<Map<K,V>> list){
    Map<K,List<V>> map = new HashMap<>();
    for(Map<K,V> m : list){
        for(Map.Entry<K,V> e : m.entrySet()){
            if( !map.containsKey(e.getKey())){
                map.put(e.getKey(), new ArrayList<>());
            }
            map.get(e.getKey()).add(e.getValue());
        }
    }
    return map;
}

您可以使用以下方法简化内部循环Map#computeIfAbsent

static <K,V> Map<K,List<V>> getMapFromTheListOld_2(List<Map<K,V>> list){
    Map<K,List<V>> map = new HashMap<>();
    for(Map<K,V> m : list){
        for(Map.Entry<K,V> e : m.entrySet()){
            map.computeIfAbsent(e.getKey(), k -> new ArrayList<>()).add(e.getValue());
        }
    }
    return map;
}

但是 IMO 两种方法并不比使用流的单线更容易。您可以添加一些新行以使其更具可读性:

static <K,V> Map<K,List<V>> getMapFromTheList(List<Map<K,V>> list){
    return list.stream()
            .flatMap(map -> map.entrySet().stream())
            .collect(Collectors.groupingBy(
                    Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
}

推荐阅读