【问题标题】:Java 8 Collectors.toMap with ArrayList as valueJava 8 Collectors.toMap 以 ArrayList 作为值
【发布时间】:2020-07-18 09:30:38
【问题描述】:

我想使用 java 8 将给定的二维数组转换为映射。 输入 - { { 1, 0 }, { 2, 0 }, { 3, 1 }, { 3, 2 } } 输出应该是形式 Map map = new HashMap(); 输出 - {1=[0], 2=[0], 3=[1, 2]}

以下是我的解决方案

for (int[] prereq : prerequisites) {
            map.computeIfAbsent(prereq[0], k -> new ArrayList<>()).add(prereq[1]);
        }

任何更好的方法,如果 for 循环可以替换为流。

【问题讨论】:

  • 你的方法看起来不错。如果您使用的是 java 9+ 并且您不打算更改列表,在这种情况下,您可以执行以下更改 map.computeIfAbsent(prereq[0], k -&gt; List.of(prereq[1]);

标签: lambda java-8 java-stream


【解决方案1】:

要通过键收集到包含多个值的 Map,请使用 Collectors.groupingBy

int[][] prerequisites = {{1, 0}, {2, 0}, {3, 1}, {3, 2}};
Map<Integer, List<Integer>> res = Arrays.stream(prerequisites).collect(
        Collectors.groupingBy(x -> x[0], Collectors.mapping(x -> x[1], Collectors.toList())));

输出:

{1=[0], 2=[0], 3=[1, 2]}

【讨论】:

  • Map> res = Arrays.stream(prerequisites).collect( Collectors.toMap(x -> x[0], x -> Arrays.asList(x[1 ]), (x1, x2) -> Arrays.asList(x1.get(0), x2.get(0))));
  • @ShashankAgrawal Acutually groupingBy 是当 map key 有多个 value 时更好的选择,toMap 通常用于单 value map 以及当您想要自己的合并功能时。阅读更多详情here
【解决方案2】:

由于您的数组行总是由一对数字组成,并且您将第一个元素视为键,而将第二个元素视为值,因此如果将它们映射到 SimpleEntry,乍一看就会很明显:​​

int[][] prerequisites = { { 1, 0 }, { 2, 0 }, { 3, 1 }, { 3, 2 } };
    Map<Integer,List<Integer>> map = 
            Arrays.stream(prerequisites)
                  .map(arr -> new AbstractMap.SimpleEntry<>(arr[0], arr[1]))
                  .collect(Collectors.groupingBy(
                            Map.Entry::getKey,
                            Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

【讨论】:

  • 完全一样,乍一看我的第一个解决方案也完全一样。
猜你喜欢
  • 2017-08-08
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-26
相关资源
最近更新 更多