java 中的集合深度克隆
Deep Cloning of Collections in java
最近我在面试中遇到了这个问题:
编写函数 return class 绘图的深层克隆实例
public class Drawing{
public List<Shape> shapes=new LinkedList<Shape>();
}
其中 shape 是一个抽象的 class 有很多具体的实现
public abstract class Shape implements Serializable{
}
谁能告诉我如何解决这个问题?我们是否需要在所有具体实现中添加克隆方法?
Shape
的每个子 class 都知道如何创建自己的深拷贝,因为这是 Serializable
实现应该做的一件事。因此,在 Drawing
和 serialize/deserialize 中迭代 Shape
对象中的列表,以创建列表中每个 Shape
的深层副本。
您还可以 use a library 比序列化方法更快。
Cloner cloner=new Cloner();
MyClass clone=cloner.deepClone(o);
// clone is a deep-clone of o
我建议使用 Apach Commons Lang 中的 SerializationUtils.clone
此方法用于深度克隆:
SomeObject cloned = org.apache.commons.lang.SerializationUtils.clone(someObject);
这是一种克隆对象的简单方法,但如果您追求性能,则不行。
您需要做的是首先序列化 List<Shape>
,然后反序列化 return Drawing
的新实例,反序列化 List
public static Drawing deepClone(Drawing drawing) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(drawing.shapes); //Serializes the drawing.shapes
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return new Drawing((LinkedList<Shape>)ois.readObject()); //Deserializing and reading
} catch (IOException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
假设您在 Drawing 中有一个构造函数,它接受一个 LinkedList<Shape>
作为参数
编辑
实现 Cloneable
接口时覆盖 clone()
方法,因此不需要在 Shape class 中添加 clone()
,但根据问题,他们希望您使用 Serializable
界面创建克隆。
最近我在面试中遇到了这个问题:
编写函数 return class 绘图的深层克隆实例
public class Drawing{
public List<Shape> shapes=new LinkedList<Shape>();
}
其中 shape 是一个抽象的 class 有很多具体的实现
public abstract class Shape implements Serializable{
}
谁能告诉我如何解决这个问题?我们是否需要在所有具体实现中添加克隆方法?
Shape
的每个子 class 都知道如何创建自己的深拷贝,因为这是 Serializable
实现应该做的一件事。因此,在 Drawing
和 serialize/deserialize 中迭代 Shape
对象中的列表,以创建列表中每个 Shape
的深层副本。
您还可以 use a library 比序列化方法更快。
Cloner cloner=new Cloner();
MyClass clone=cloner.deepClone(o);
// clone is a deep-clone of o
我建议使用 Apach Commons Lang 中的 SerializationUtils.clone
此方法用于深度克隆:
SomeObject cloned = org.apache.commons.lang.SerializationUtils.clone(someObject);
这是一种克隆对象的简单方法,但如果您追求性能,则不行。
您需要做的是首先序列化 List<Shape>
,然后反序列化 return Drawing
的新实例,反序列化 List
public static Drawing deepClone(Drawing drawing) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(drawing.shapes); //Serializes the drawing.shapes
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return new Drawing((LinkedList<Shape>)ois.readObject()); //Deserializing and reading
} catch (IOException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
假设您在 Drawing 中有一个构造函数,它接受一个 LinkedList<Shape>
作为参数
编辑
实现 Cloneable
接口时覆盖 clone()
方法,因此不需要在 Shape class 中添加 clone()
,但根据问题,他们希望您使用 Serializable
界面创建克隆。