Reputation: 728
In about 30 days, I'm going to participate in a Java contest. At the contest, we'll be handed a computer with Eclipse and the Java 1.7 API. I'm practicing on the tasks from the previous year's contest, and I repeatedly find the need to deep clone a list. With limited time and the only the Java 1.7 API available, is there any way to do this?
I've seen several solutions to this already, including
Cloneable
interface.List
is holding, and iterate over the elements.But these solutions are either not available to me at the contest or too time consuming. Right now, I need to deep clone an ArrayList
of objects that also contain ArrayList
s.
Does anyone know if this is even possible? Thanks for all help!
Upvotes: 1
Views: 135
Reputation: 18415
Instead of invoking clone you could also write everything to a ByteArrayOutputStream and read it in again.
See if this helps you:
static public <T> T deepCopy(T oldObj) throws Exception {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream( bos);
oos.writeObject( oldObj);
oos.flush();
ByteArrayInputStream bin = new ByteArrayInputStream( bos.toByteArray());
ois = new ObjectInputStream( bin);
return (T) ois.readObject();
} catch( Exception e) {
e.printStackTrace();
throw ( e);
} finally {
if( oos != null) {
oos.close();
}
if( ois != null) {
ois.close();
}
}
}
Usage e. g.:
public class Testing {
public static void main(String[] args) throws Exception {
List<Object> list = new ArrayList<>();
list.add( "A");
list.add( "B");
list.add( 1);
list.add( 2);
list.add( new BigDecimal( 123.456839572935879238579238754938741321321321321593857));
list.add( new MyParentObject( 12345, "abcdef", new MyChildObject( "child")));
List clone = (List) Tools.deepCopy( list);
for( Object obj: clone) {
System.out.println( obj);
}
System.exit(0);
}
private static class MyParentObject implements Serializable {
int a;
String b;
MyChildObject child;
public MyParentObject(int a, String b, MyChildObject child) {
super();
this.a = a;
this.b = b;
this.child = child;
}
public String toString() {
return a + ", " + b + ", " + child;
}
}
private static class MyChildObject implements Serializable {
String s;
public MyChildObject( String s) {
this.s = s;
}
public String toString() {
return s;
}
}
}
Output:
A
B
1
2
123.456839572935876958581502549350261688232421875
12345, abcdef, child
Upvotes: 0
Reputation: 42176
This is going to depend entirely on what's in the List. So, the short answer is: no.
You could try serializing the whole List, but that requires everything in the List also be serializable. You could write a deepClone() method that calls the clone() method on everything in the List, but that depends on every Object in the List correctly implementing the clone() method.
The whole reason this is a contest question is there isn't a quick one-size-fits-all solution.
Upvotes: 2