【问题标题】:Creating an ArrayList of ArrayList having one additional element compared to another ArrayList of ArrayList创建一个 ArrayList 的 ArrayList,与 ArrayList 的另一个 ArrayList 相比,它具有一个附加元素
【发布时间】:2016-07-11 21:39:18
【问题描述】:

我有一个 ArrayList (alal) 和一个 ArrayList(al) 的 ArrayList。我想将 al 插入 alal,但我希望 alal.get(0) 包含 al 的所有内容以及添加的元素 100。我认为最简单的方法是先做

alal.add(al);

然后访问它的第 0 个元素,并添加一个 100,比如

alal.get(0).add(100);

但是,这样做的问题是 al 的内容也会发生变化,因为它是一个对象,因此 alal 持有它的引用而不是值。

我在下面尝试过。请告诉我这是否是正确的做法,或提出改进建议。

import java.util.ArrayList;

public class additionalal {
    public static void main(String[] args) {
        ArrayList<ArrayList<Integer>> alal = new ArrayList<ArrayList<Integer>>();
        ArrayList<Integer> al = new ArrayList<Integer>();
        al.add(1);al.add(2);al.add(3);

        //WRONG
//      alal.add(al);
//      alal.get(0).add(100);

        //CORRECT
        ArrayList<Integer> alextra = new ArrayList<Integer>();
        alextra.addAll(al);
        alextra.add(100);
        alal.add(alextra);

        System.out.println(alal);
        System.out.println(al);
    }
}

【问题讨论】:

  • 有什么问题?
  • 如果您希望 alal.get(0) 返回列表 al 的内容,那么您应该将 al(实际上是它的副本)插入到元素 0 中:alal.add(0, al)

标签: java arraylist pass-by-reference


【解决方案1】:

添加时将您的列表包装成一个新的ArrayList,从而克隆它:

alal.add(new ArrayList<>(al));
alal.get(0).add(100);

但请注意,列表中的元素不会与它一起克隆。当您有Integers 的列表时,这是可以的,但在存储具有动态属性的类型的元素时可能会导致意外行为。例如,假设您要存储 ListLists 的 Persons :

class Person {
    String name = "";

    public String getName() {
        return this.name;
    }

    public void setName(String otherName) {
        this.name = otherName;
    }

    public String toString() {
        return "Person[name=" + this.name + ']';
    }
}

现在,我创建一个Person,将其放入List persons,然后将persons 的副本放入personGroups

Person user = new Person();
user.setName("saltandwater");

List<Person> persons = new ArrayList<>();
persons.add(user);

List<List<Person>> personGroups = new ArrayList<>();
personGroups.add(new ArrayList<>(persons));

打印两个列表会产生类似

persons: [Person[name=saltandwater]]
personGroups: [[Person[name=saltandwater]]]

现在,将新的 Person 添加到 persons 不会修改 personGroups。但是,由于user 未被克隆(仅persons 列表被克隆),user.name 中的更改将反映在两个列表中:

user.setName("Mr. Yetti");

会导致

persons: [Person[name=Mr. Yetti]]
personGroups: [[Person[name=Mr. Yetti]]]

【讨论】:

  • 谢谢,这很好。但是,当您说“请注意,列表中的元素并没有与它一起克隆”时,您的意思是什么。我看到 alal 中的所有元素,即 [[1, 2, 3, 100]]。
  • @saltandwater:增强了答案。这与您的情况并不特别相关,但仍需牢记。
猜你喜欢
  • 1970-01-01
  • 2012-03-28
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
相关资源
最近更新 更多