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


  alal.add(al);


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


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


但是,这样做的问题在于al的内容也发生了变化,因为它是Object,所以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);
    }
}

最佳答案

添加时将列表包装到新的ArrayList中,从而克隆它:

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


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

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]]]

08-27 08:58