ArrayList 的 Java ArrayList

新手上路,请多包涵

以下代码输出

[[100, 200, 300], [100, 200, 300]].

然而,我期望的是

[[100, 200, 300], [100, 200]],

我哪里错了?

 public static void main(String[] args) {
    ArrayList<ArrayList<Integer>> outer = new ArrayList<ArrayList<Integer>>();
    ArrayList<Integer> inner = new ArrayList<Integer>();

    inner.add(100);
    inner.add(200);

    outer.add(inner);
    outer.add(inner);

    outer.get(0).add(300);

    System.out.println(outer);

}

原文由 Jie 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 453
2 个回答

您正在将对同一内部 ArrayList 的引用添加到外部列表两次。因此,当您更改内部列表(通过添加 300)时,您会在“两个”内部列表中看到它(实际上只有一个内部列表,其两个引用存储在外部列表中)。

为了得到你想要的结果,你应该创建一个新的内部列表:

 public static void main(String[] args) {
    ArrayList<ArrayList<Integer>> outer = new ArrayList<ArrayList<Integer>>();
    ArrayList<Integer> inner = new ArrayList<Integer>();

    inner.add(100);
    inner.add(200);
    outer.add(inner); // add first list
    inner = new ArrayList<Integer>(inner); // create a new inner list that has the same content as
                                           // the original inner list
    outer.add(inner); // add second list

    outer.get(0).add(300); // changes only the first inner list

    System.out.println(outer);
}

原文由 Eran 发布,翻译遵循 CC BY-SA 3.0 许可协议

在阅读此答案之前,您可能需要先熟悉一下 变量、对象和引用之间有什么区别?


这就是你现在拥有的

ArrayList<ArrayList<Integer>> outer = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> inner = new ArrayList<Integer>();

将创造

outer -> []
inner -> []

它创建两个 单独 的列表并将对它们的引用存储在变量 outerinner 中。


inner.add(100);
inner.add(200);

你的情况看起来像

outer -> []
inner -> [100, 200]


令人困惑的部分来了

outer.add(inner);
outer.add(inner);

这里 inner 变量的 _值_(因此 引用 列表 [100, 200])被放置在 outer 列表两次。这意味着 outer “指向” [100, 200] 列表两次

//note: `reference1` == `reference2` (like 42 == 42) since they point to same object
outer -> [ reference1, reference2 ]
              |             |
      +-------+             |
      +---------------------+
      ↓
inner +-> [100, 200]

这意味着,如果您更改列表 [100, 200] 的状态,您将能够使用 outer.get(0)outer.get(1)inner ,sinced它们是对同一个列表的引用。

所以如果我们使用

outer.get(0).add(300);

outer.get(0) 返回对与 inner 相同列表的引用和 add(300) 向该列表添加新元素。这意味着在它之后新的情况会是这样的

outer -> [ reference1 , reference2 ]
              |             |
      +-------+             |
      +---------------------+
      ↓
inner -> [100, 200, 300]

这就是为什么当你打印 outer 你会看到

[[100, 200, 300], [100, 200, 300]].
 ^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^
   from get(0)      from get(1)


您实际需要的是创建单独的列表,以便 reference1reference2 将指向两个单独的列表。就像是

outer  -> []
inner1 -> [100, 200]
inner2 -> [100, 200]

稍后将组织成

outer -> [ reference1 , reference2 ]
              |             |
       +------+             |
       ↓                    |
inner1 -> [100, 200]        |
                            |
       +--------------------+
       ↓
inner2 -> [100, 200]

你可以这样做

List<List<Integer>> outer = new ArrayList<List<Integer>>();
List<Integer> inner1 = new ArrayList<Integer>();
List<Integer> inner2 = new ArrayList<Integer>();

inner1.add(100);
inner1.add(200);

inner2.add(100);
inner2.add(200);

outer.add(inner1);
outer.add(inner2);

outer.get(0).add(300);

System.out.println(outer);
//Output: [[100, 200, 300], [100, 200]]

原文由 Pshemo 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏