【问题标题】:Adding item to LinkedList of ArrayLists size error将项目添加到 ArrayLists 大小错误的 LinkedList
【发布时间】:2013-07-26 09:17:56
【问题描述】:

好的,在我的程序中,我创建了 ArrayLists 的 LinkedList:

 List<Marker> list1 = new ArrayList<Marker>();
 LinkedList<List<Marker>> list2 = new LinkedList<List<Marker>>();

向 list1 添加项目时一切正常:list1.add(mark);

但是当我尝试将我的 list1 添加到 list2 (list2.add(list1)) 时,我遇到了奇怪的事情: list2 中的每个列表大小都等于最后添加的列表大小+1,我什至无法使用(例如)list2.getFirst().get(0); 读取这些列表项 - 这样做我得到了错误;

例如我正在这样做:

mark.addSomeInfo();
list1.add(mark);
list2.add(list1);
mark.addSomeInfo();
list1.add(mark);
list2.add(list1);
mark.addSomeInfo();
list1.add(mark);
list2.add(list1);

我需要得到这个:

list2.get(0).size() = 1;
list2.get(1).size() = 2;
list2.get(2).size() = 3;

但是我得到了这个:

list2.get(0).size() = 4;
list2.get(1).size() = 4;
list2.get(2).size() = 4;

为什么?我做错了什么?

【问题讨论】:

    标签: java arraylist size


    【解决方案1】:

    LinkedList&lt;List&lt;Marker&gt;&gt; list2add 方法不会创建您添加到其中的列表的副本。它仅将list1 的引用添加到list2。因此,本质上您的 list2 包含对同一列表的 3 个引用。

    您要做的是在将副本放入list2 时自己创建副本

    mark.addSomeInfo();
    list1.add(mark);
    list2.add(new ArrayList<Mark>(list1));
    mark.addSomeInfo();
    list1.add(mark);
    list2.add(new ArrayList<Mark>(list1));
    mark.addSomeInfo();
    list1.add(mark);
    list2.add(new ArrayList<Mark>(list1));
    

    【讨论】:

    • 还有一个问题。不将项目添加到 list1 而是更新它们然后将 list1 作为新元素放入 list2 怎么样?
    • @user2595870 嗯,如果我理解正确,那是行不通的。问题是new ArrayList&lt;Mark&gt;(list1) 不执行深层复制。这意味着您将获得一个新列表,其中包含与旧列表相同的对象。每当您更改对象的状态时,指向该对象的所有引用也将得到更新。为了做你想做的事,我建议添加一个复制构造函数Mark(Mark m)。然后通过迭代旧列表并将复制构造的副本添加到新列表来创建一个新列表。
    • 是的,你没有理解我的意思。现在只剩下一个问题 - 我正在使用适用于 android 的谷歌地图,我需要制作标记克隆,如何做到这一点?因为 Markers 没有复制/克隆功能。
    • 哦,我对安卓的谷歌地图一无所知,作为一个新问题提出这个问题可能是值得的。如果标记具有内部值的获取器,您可能只需编写自己的静态复制函数,该函数接受一个标记并返回一个复制的标记。
    【解决方案2】:

    List2 中的引用指向 List1 .. 这就是为什么所有相​​同的 SOP 给出相同的结果 4

    【讨论】:

      【解决方案3】:

      list1 只是您代码中的一个引用。所以本质上,您将相同的arraylist 对象一次又一次地添加到linkedlist。最后,在您的示例中,相同的 arraylist 被复制了 3 次,大小为 4。

      【讨论】:

        【解决方案4】:

        LinkedList 的所有引用都指向相同的 List 对象,即 list1,因此它打印大小为 4。

        由于您使用了支持重复元素的ArrayList,因此每次添加标记对象时都会创建一个重复条目。

        【讨论】:

          【解决方案5】:

          在 list2 的第 0、1 和 2 位,您添加了相同的 list1 对象。 由

          改变
           list1.add(mark);
          

          由于上述函数在您的代码中被调用了四次。因此 list1 引用现在指向堆上的对象,该对象有 4 个项目,因此 list1 的所有 3 项的大小有 4 个元素。

          【讨论】:

            【解决方案6】:
            mark.addSomeInfo();
            list1.add(mark);  //this gets added to list each time you add it --1
            list2.add(list1); //this gets added too as many times as you add list1
            mark.addSomeInfo();
            list1.add(mark);  // 2
            list2.add(list1);  //2
            mark.addSomeInfo();
            list1.add(mark);  // 3
            list2.add(list1);  // 3
            

            因此,在此之后,您将在 list1 中拥有 3 个元素,在 list2 中拥有 3 个列表

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多