有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

arraylist如何在java中将List<Map<K,V>>转换为Map<K,List<V>>

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

Input

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

Output

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

我尝试了以下代码

Code


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())));
    }  

有没有更好的办法?更简单的方法还是更有效的方法


共 (2) 个答案

  1. # 1 楼答案

    替代方案可能如下所示:

    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;
    }
    

    但在我看来,这两种方法并不比使用流的一行程序更简单。您可以添加一些新行以使其更具可读性:

    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())));
    }
    
  2. # 2 楼答案

    Java流api是实现这一点的最佳且高效的方法。它在处理集合时速度很快,因为它支持使用流并行执行集合数据。 这就是在Java8中引入流api的目的,目的是减少评估和计算数据时的大量循环。 因此,从我的角度来看,您的代码是正确和高效的