我有一个详细信息类型的ArrayList集合1。我将它分配给另一个集合2来对它进行操作,这样它就不会影响集合1.但是我看到集合1受到影响,因为引用了对象。 但我希望有两个不同的内存参考集合 - plz帮助我。
详细信息类 -
public class Details implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean enabled;
private int number;
public Details() {
}
public Details(int number, boolean enabled) {
this.enabled = enabled;
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public boolean getEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
主要课程 -
public static void main(String[] args) {
List<Details> detailsList = new ArrayList<Details>();
detailsList.add(new Details(10, false));
detailsList.add(new Details(20, false));
List<Details> newDetailsList = new ArrayList<Details>(detailsList);
for(Details d : newDetailsList) {
d.setEnabled(true);
d.setNumber(50);
}
for(Details d : detailsList) {
System.out.println("---" + d.getEnabled());
System.out.println("---" + d.getNumber());
}
}
输出 -
---true
---50
---true
---50
我从newDetailsList
创建一个新集合detailsList
并修改它......我看到更改已应用于detailsList集合。我怎么能避免那个
答案 0 :(得分:1)
集合仅保存对象的引用。集合的副本只是一个新的引用,它包含对相同对象的相同引用。
除非您对集合中的所有对象进行 deep clone ,否则这将永远不会有效。
这对于要复制的对象只是implements Clonable
并不简单,并且有很多注意事项和almost impossible to get correct, to the point of not even bothering except in very simple cases,特别是如果有对象没有来源。
因此,Details
对象的所有实例变量也必须被深度复制,作为其所有实例成员,以及他们的,以及他们的,以及他们的。而且你必须避免循环引用。就像我说的那样,并不像听起来那么简单。
有时这是不可能的,尤其是mutable
个对象。但是有一个解决方案。
使Details
对象不可变,并从原始对象创建新实例,并在构造新实例时设置所需的新值。
public class Details
{
private final Boolean enabled;
private final Integer number;
public Details(@Nonnull final Integer number, @Nonnull Boolean enabled)
{
this.enabled = enabled;
this.number = number;
}
public int getNumber() { return number;}
public boolean getEnabled() { return enabled; }
}
一个好的方便工厂方法是:
public static Details newDetailsFromOldDetails(@Nonnull final Details details, @Nullable Integer number, @Nullable Boolean enabled)
{
final Integer n = number == null ? details.getNumber() : number;
final Boolean e = flag == null ? details.getBoolean() : enabled;
return new Details(n, e)
}
答案 1 :(得分:0)
您复制列表,但不复制列表中包含的项。因此,如果您修改复制的集合中的项目,更改仍将显示在原始集合中的项目中。您可能需要deep copy,这需要创建一个机制,通过该机制可以复制Details
个对象,然后将原始列表项的副本添加到新列表中。相反,使用ArrayList
的拷贝构造函数只是复制引用(即浅拷贝)。
答案 2 :(得分:-1)
克隆每个详细信息对象类型,如下所示 -
List<Details> newDetailsList = new ArrayList<Details>();
for(Details t : detailsList) {
newDetailsList.add(t.clone());
}
public Details clone() {
return new Details(this.number, this.enabled);
}
但是对于我在我的应用程序中真正使用的对象来说,这是不可能的。