假设我们有:
public class Test {
private List<String> mWorkList;
private List<String> mOriginalList;
public Test(List<String> list) {
mWorkList = list;
mOriginalList = list;
}
public void updateData(List<String> newList) {
mWorkList.clear();
mWorkList.addAll(newList);
}
}
我只想更改mWorkList
但mOriginalList
在我致电updateData(List<String>)
时也会更改。
那么我应该如何保持mOriginalList
最初在构造函数中分配?
答案 0 :(得分:4)
您应该在函数中创建新的
logger.debug("SETTINGS: " + System.getProperties() );
...
file.encoding.pkg=sun.io
javax.servlet.request.encoding=UTF-8
sun.jnu.encoding=ANSI_X3.4-1968
file.encoding=UTF-8
sun.io.unicode.encoding=UnicodeLittle
....
对象,因为所有列表都引用了一个变量
List
答案 1 :(得分:4)
您使用
设置了具有相同实例引用的两个列表mWorkList = list;
mOriginalList = list;
您需要通过复制列表为mOriginalList
创建新实例。这可以使用ArrayList(Collection)
的构造函数之一完成。
mOriginalList = new ArrayList<>(list);
请注意,两个列表中的实例都相同,因此如果您更新list
中的实例,则会在mOriginalList
中更改该实例。如果你想打破这个链接,你需要克隆列表及其内容。
答案 2 :(得分:3)
在Java中,您可以通过引用传递变量。这意味着,无论何时执行mWorkList = list
之类的作业,变量mWorkList
都会指向相同位于list
当前指向的内存中。如果您执行mOriginalList = list
,则mOriginalList
也会指向该位置。即所有三个列表在此时引用相同的对象。
如果您需要独立列表,则需要复制列表中的所有值到新列表,如下所示:
List<String> myList = new ArrayList<>(otherList);
ArrayList
的此构造函数会自动添加其他列表中的所有值,此处为documentation。
您的代码可能如下所示:
public Test(List<String> list) {
mWorkList = new ArrayList<>(list);
mOriginalList = new ArrayList<>(list);
}
或者如果您不打算更改mOriginalList
,也可以将其保留为mOriginalList = list
。但请记住,如果用户对list
(来自您班级的外部)进行了更改,他们也会反映在mOriginalList
中,这很容易导致令人讨厌的错误。
答案 3 :(得分:2)
每当您将对象分配给另一个对象时,只会分配引用(浅拷贝)。您应该调用复制构造函数来进行深层复制。
public class Test {
private List<String> mWorkList;
private List<String> mOriginalList;
public Test(List<String> list) {
mWorkList = new ArrayList<>(list);
mOriginalList = new ArrayList<>(list);
}
public void updateData(List<String> newList) {
mWorkList.clear();
mWorkList.addAll(newList);
}
}
答案 4 :(得分:1)
在java中,每个变量都是一个引用,所以在这种情况下,如果你改变其中一个变量,那么这两个变量都是正常的。
要保留副本,您必须创建一个新对象并克隆原始对象。