[英]Check if an ArrayList contains the same element as another ArrayList
[英]Clonning ArrayList element to the same ArrayList
我有一个包含对象的ArrayList
。 (这个对象是类,每个对象都包含大量的信息,正是这些对象代表了大型发电机,因此无法逐一复制属性)。
例子:
ArrayList arr = {ob1, ob2, ob3, ob4, ob5}
所以我尝试做的是将对象(ob1)克隆到位置 5。
arr.set(4, arr.get(0));
但不知何故,这样做,ob5 不是复制 ob ob1,它是 ob1,所以如果我改变 ob5,ob1 也会改变。
这是 ArrayLists 固有的东西吗? 如果我改用 Lists 有什么区别吗?
ArrayList 保存引用是的。 但是你可以克隆它(注意!但它将是浅拷贝 - 它不会克隆内部对象https://stackoverflow.com/a/13434779/1111527 )
private class JustToCheck implements Cloneable {
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
然后像这样使用
JustToCheck ob1 = new JustToCheck();
JustToCheck ob2 = ob1;
List<JustToCheck> arr = new ArrayList<JustToCheck>();
arr.add(ob1);
arr.add(ob2);
System.out.println(arr.get(0).toString() + ": " + arr.get(1).toString());
try {
arr.set(1, (JustToCheck) ob1.clone());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(arr.get(0).toString() + ": " + arr.get(1).toString());
输出是
example$JustToCheck@1c39a2d: example$JustToCheck@1c39a2d
example$JustToCheck@1c39a2d: example$JustToCheck@bf2d5e
PS - 我已经检查了答案https://stackoverflow.com/a/13434813/1111527 中的问题
有一些不可变的类
Java6
String a = new String("a");
String b = a;
b += "b";
System.out.println("a = " + a); // a = a
System.out.println("b = " + b); // b = ab
这是因为您正在执行卷影复制而不是深层复制。
浅拷贝:如果在Obj-1
上执行浅拷贝,则复制它但不复制其包含的对象。 包含的对象Obj-1
和Obj-2
受克隆 Obj-2 更改的影响。 当类实现 java.lang.Cloneable 接口时,Java 默认支持对象的浅层克隆。
深副本:如果一个深拷贝是在执行obj-1
所示,那么不仅obj-
1已经被复制,但对象包含在它已被复制为好。 序列化可用于实现深度克隆。 通过序列化进行深度克隆的开发速度更快且更易于维护,但会带来性能开销。 来源
深拷贝的一个例子:
class Student implements Cloneable {
//Contained object
private Subject subj;
private String name;
public Subject getSubj() {..}
public String getName() {..}
public Object clone() {
//Deep copy
Student s = new Student(name, subj.getName());
return s;
}
}
在 Java 中的任何地方都是如此。 除非您明确这样做,否则不会复制任何内容。 (确实,有些对象是故意无法复制的。)
您需要制作ElectricGenerator
的副本。 最常见的选项是引入复制构造函数或实现克隆方法。 然而,这两种解决方案都需要复制所有这些属性。
一旦你有了它,你就可以做到
//copy constructor
arr.add( new ElectricGenerator( arr.get( 0 ) ) );
//clone
arr.add( arr.get( 0 ).clone() );
另一种方法是序列化/反序列化对象
这不符合 ArrayList,这是一个 java 特性。 不创建新对象,只传递一个引用。 因此 ArrayList 存储了两个引用。 您必须使用对象的 .clone() 方法。
arr.set(4, arr.get(0).clone());
这将创建对象的新副本,即使此副本将是浅的。 如果需要,您必须覆盖 clone 方法以使其成为深层副本。
不,这是因为在 Java 中,您创建了对对象的引用,因此即使您不使用 ArrayList 并执行以下操作:
String a = new String("a");
String b = a;
b += "b";
a 和 b 都等于“ab”。
(例外是像 int 这样的基本类型(但不是 Integer 的实例,有不同的东西))。
所以你的问题的答案在这里: 如何通过值复制对象,而不是通过引用和这里: http : //www.itcsolutions.eu/2010/12/29/tutorial-java-6-4-2-how -to-copy-values-of-an-array-into-another-array/
该列表仅包含指向对象的指针..
如果您将 ob1 移动到 ob5 会发生什么,您告诉列表将指针指向 ob5 的指针所在的 ob1,因此丢失指向 ob5 的指针并复制指向 ob1 的指针...
您将需要创建一个包含重复值的其他对象,然后将此对象分配给位置 4
对象变量不同于原始数据类型。
int x = 2;
int y = x;
x 和 y 指的是不同的内存位置。
MyClass x = new MyClass();
MyClass y = x;
x 和 y 引用相同的内存位置,但该位置有两个引用。 对其中一个所做的任何更改都会改变另一个。 解决这个问题的方法是实现Cloneable
并使用.clone()
方法。
shallow copying
创建同一个类的新实例,并将所有字段复制到新实例并返回它。 Object 类提供了一个 clone 方法,并提供了对浅拷贝的支持。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.