【问题标题】:Adding to double Arraylist in HashMap在 HashMap 中添加到双 Arraylist
【发布时间】:2021-12-30 18:04:34
【问题描述】:

我正在尝试在 java 中添加加起来达到某个数字的对,我尝试这样做的方法之一是在我的 HashMap 中创建一个双 ArrayList。如果我将 1 和 2 添加到我的列表中,我将获得 3 作为我的密钥。例如:

    HashMap<Integer, ArrayList<ArrayList<Integer>>> map = new HashMap<>();
    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    map.put(list.get(0) + list.get(1), new ArrayList<>(list));

输出如下所示

   Key: 3 Value: [[1,2]]

如果我要再添加一对

  Key: 3 Value: [[1,2],[0,3]]

但我不断收到“方法不适用于类型 HashMap> 不适用于参数 (int, new ArrayList(list))”

我也试过

    new ArrayList<>(new ArrayList<>(list))

认为我可能需要先初始化更大的矩阵,但遗憾的是我最终遇到了同样的错误。

【问题讨论】:

  • 如果您在添加值之前和之后显示地图,这将对每个人(包括那些将寻求您的问题寻求帮助的人)都有帮助。添加一些值,显示地图。添加更多,再次显示地图。
  • 好主意!我刚刚添加了一些输出,因为我没有看到与我正在寻找的内容非常相似的 StackOverflow 帖子。

标签: java arraylist hashmap


【解决方案1】:

这一行:

new ArrayList<>(list)

创建一个平面ArrayList&lt;Integer&gt;,而HashMap 期待ArrayList&lt;ArrayList&lt;Integer&gt;&gt;。出于同样的原因,new ArrayList&lt;&gt;(new ArrayList&lt;&gt;(list)) 也创建了一个平面整数列表,因为您只是做了两次相同的事情。请参阅API document ArrayList

考虑到二维列表设置,这是一种可行的方法:

HashMap<Integer, List<List<Integer>>> map = new HashMap<>();
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
List<List<Integer>> outer = new ArrayList<>();
outer.add(list);
map.put(list.get(0) + list.get(1), outer);

【讨论】:

  • 两者有什么区别? ArrayList 列表会像这样 [[1,2][2,3]] 吗? new ArrayList(new ArrayList(list)) 会做什么?还是语法错误?
  • 是的 List&lt;List&lt;Integer&gt;&gt; 看起来像 [[1,2,3], [1,2]]。至于new ArrayList&lt;&gt;(new ArrayList&lt;&gt;(list)),由于list 是一个像[1,2,3] 的一维列表,new ArrayList&lt;&gt;(list) 也返回一个像[1,2,3] 的一维列表。因此new ArrayList&lt;&gt;(new ArrayList&lt;&gt;(list)) 仍然返回一个像 [1,2,3] 这样的一维列表。语法编译,它只是没有做你认为它会做的事情。
  • 答案中链接中的api doc指定当Collection传入ArrayList的构造函数时,它“构造一个包含指定集合元素的列表”,而不是列表列表,包含指定集合的​​元素。
【解决方案2】:

您还可以创建一些 lambdas 来促进这一点。例如。

Map<Integer, List<List<Integer>>> map1 = new HashMap<>();

创建一个对列表元素求和的函数。

Function<List<Integer>, Integer> sum =
        list -> list.stream()
        .mapToInt(Integer::intValue).sum();

然后创建一个BiConsumer 来获取列表对和现有地图,并在需要时添加它们。 computeIfAbsent,如果键为空或不存在,则输入键的值。返回该列表,以便可以将该对添加到新创建的列表中。

BiConsumer<List<Integer>, Map<Integer,
           List<List<Integer>>>> addToMap =
        (pair, map) -> {
            map.computeIfAbsent(sum.apply(pair),
                    v -> new ArrayList<>()).add(pair);
        };

把它们放在一起。

addToMap.accept(List.of(1,2), map1);
addToMap.accept(List.of(0,4), map1);
addToMap.accept(List.of(1,5), map1);
addToMap.accept(List.of(0,3), map1);
addToMap.accept(List.of(-1,5), map1);
addToMap.accept(List.of(-1,2,3),map1);

map1.entrySet().forEach(System.out::println);

打印

3=[[1, 2], [0, 3]]
4=[[0, 4], [-1, 5], [-1, 2, 3]]
6=[[1, 5]]

如您所见,这不会对“对”施加任何大小限制。

这对于您想要的东西可能有点过头了,但您可能可以使用一些元素。另请注意,上面的List.of 是不可变的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多