Примерно через 30 дней я собираюсь участвовать в конкурсе Java. На конкурсе нам будет вручен компьютер с Eclipse и API Java 1.7. Я занимаюсь задачами конкурса предыдущего года, и я неоднократно нахожу потребность в глубоком клонировании списка. С ограниченным временем и единственным доступным API Java 1.7, есть ли способ сделать это?
Я уже видел несколько решений для этого, включая
Cloneable
.List
, и выполните итерацию по элементам. Но эти решения либо недоступны мне на конкурсе, либо слишком много времени. Прямо сейчас мне нужно глубоко клонировать ArrayList
объектов, которые также содержат ArrayList
s.
Кто-нибудь знает, возможно ли это? Спасибо за помощь!
Это будет полностью зависеть от того, что в Списке. Итак, короткий ответ: нет.
Вы можете попробовать сериализовать весь список, но это требует, чтобы все в Списке также можно было сериализовать. Вы можете написать метод deepClone(), который вызывает метод clone() во всем в списке, но это зависит от каждого объекта в списке, который правильно реализует метод clone().
Вся причина, по которой этот вопрос является предметом конкурса, заключается в том, что нет быстрого решения для одного размера.
Вместо вызова клона вы также можете написать все в ByteArrayOutputStream и прочитать его снова.
Посмотрите, поможет ли это вам:
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();
}
}
}
Использование, например:
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;
}
}
}
Вывод:
A
B
1
2
123.456839572935876958581502549350261688232421875
12345, abcdef, child