Java嵌套ArrayList未正确添加

4

我一直在尝试使用嵌套的ArrayList方法,但我遇到了问题。

public static void main(String[] args) {
    List<List<Integer>> list = new ArrayList<>();
    List<Integer> subList = new ArrayList<Integer>(){{
        add(1);
        add(2);
    }};
    list.add(subList);
    subList.clear();
    subList.add(3);
    subList.add(4);
    list.add(subList);
    System.out.println(list);
}

这不会得到预期的输出。结果是:
[[3, 4], [3, 4]]

而不是[[1,2],[3,4]]

我的代码有什么问题。

编辑:我的代码还有几个问题。我应该创建一个新的问题还是在这里添加?


请添加正确的标签。 - BlackPearl
5
你只是在列表中添加子列表的引用。你需要创建一个新的子列表,而不是清空旧的子列表。 - MrTux
你所创建的内容为:list = [sublist,sublist] 请注意,你只有一个子列表,并有两个对它的引用。 - Robert
1个回答

12

我建议不要使用双大括号初始化new ArrayList<Integer>{{ }},因为它是一种反模式,并且会创建匿名内部类。

至于错误,你应该初始化一个新的列表而不是clear()

public static void main(String[] args) {
    List<List<Integer>> list = new ArrayList<>();
    List<Integer> subList = new ArrayList<>();
    subList.add(1);
    subList.add(2);
    list.add(subList);
    subList = new ArrayList<>();
    subList.add(3);
    subList.add(4);
    list.add(subList);
    System.out.println(list);
}

调用clear方法不会改变对ArrayList的引用,它仍将指向同一个对象。您应该通过调用subList = new ArrayList<>()来创建一个新的引用。

关于双括号初始化的副作用的好读物

https://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/

编辑:如@NoDataFound建议的那样,如果您使用的是Java 8+,创建列表的过程可以更加简化。

如果您使用的是Java 8,则可以使用以下方式创建列表:

List<Integer> subList = Arrays.asList(1, 2);

如果您正在使用Java 9+,您可以利用

List<Integer> subList = List.of(1, 2);

4
我非常认同双括号语法的问题。通常使用它的人并不理解它的真正含义,因为那些真正理解它含义的人一般都避免使用。它是一种丑陋的语法。当然,您对于问题本质的看法也是正确的。 - John Bollinger
你应该补充说明,调用 new ArrayList + add 可以完全被 Arrays.asList(1, 2)Arrays.asList(3, 4) 替代,或者在 Java 9++ 中使用 List.of(1, 2)List.of(3, 4) - NoDataFound
是的,@JohnBollinger。这就是为什么我认为我应该加上这一点,即使它似乎与实际问题无关。 - BlackPearl
@NoDataFound 为真。将添加。 - BlackPearl
非常感谢 @BlackPearl..! - user11485720

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接