![](/img/trans.png)
[英]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.