У меня есть два списка (list1 и list2) содержащий ссылки на некоторые объекты, где некоторые записи списка могут указать на тот же объект. Затем по различным причинам я сериализирую эти списки в два отдельных файла. Наконец, когда я десериализовываю списки, я хотел бы удостовериться, что я не воссоздаю больше объектов, чем необходимый. Другими словами, для некоторой записи List1 должно все еще быть возможно указать на тот же объект как некоторая запись в List2.
MyObject obj = new MyObject();
List list1 = new ArrayList();
List list2 = new ArrayList();
list1.add(obj);
list2.add(obj);
// serialize to file1.ser
ObjectOutputStream oos = new ObjectOutputStream(...);
oos.writeObject(list1);
oos.close();
// serialize to file2.ser
oos = new ObjectOutputStream(...);
oos.writeObject(list2);
oos.close();
Я думаю, что разделяет 3.4, и 2 спецификации говорят, что десериализация строго приводит к созданию новых объектов, но я не уверен. Если так, некоторые возможные решения могли бы включить:
Существует ли простой способ гарантировать, что объекты не дублированы после десериализации?
Спасибо.
После десериализации второго списка вы может перебирать элементы и заменять дубликаты ссылкой на первый список.
Согласно 3.7 Метод readResolve метод readResolve ()
не вызывается для объекта, пока объект не будет полностью построен.
Я думаю, что в разделах 3.4 и A.2 спецификации говорится, что десериализация строго приводит к созданию новых объектов, , но я не уверен. Если так , некоторые возможные решения могут включать: ...
2, Создание «класса контейнера» для хранения всего и затем сериализацию этого класса контейнера.
Я читаю эти утверждения как : «Если я понимаю, что десериализация всегда создает новые объекты неверно, то решение №2 записи обоих списков, заключенных в контейнерный класс, в один поток, является приемлемым решением»
. ] Если я вас правильно понимаю, это означает, что вы думаете, что запись через один контейнер, содержащий оба списка, не сработает, потому что это все равно приведет к дублированию объектов («строго приводит к ... новым объектам»). Это неверно. При написании графа объектов (вашего класса-оболочки) каждый объект сериализуется только один раз, независимо от того, сколько вхождений в графе. Когда график считывается обратно, этот объект не дублируется.
http://java.sun.com/javase/6/docs/api/java/io/ObjectOutputStream.html
Механизм сериализации по умолчанию для объекта записывает класс объекта, подпись класса и значения всех непереходных и нестатических полей. Ссылки на другие объекты (кроме переходных или статических полей) также вызывают запись этих объектов. Множественные ссылки на один объект кодируются с использованием механизма совместного использования ссылок, так что графы объектов могут быть восстановлены до той же формы, что и при записи оригинала.
Итак, если можете, используйте вариант №2.
Создание «контейнерного класса» для хранения всего и последующая сериализация контейнерного класса.
Вы можете переопределить метод readResolve ()
, чтобы заменить то, что читается из потока, чем угодно.
private Object readResolve() throws ObjectStreamException {
...
}
Обычно это используется для принуждения синглтонов. До Java 5 он также использовался для типизированных перечислений. Я никогда не видел, чтобы он использовался для этого, кроме сценария, но я думаю, что нет причин, по которым этого не могло быть.
Теперь это будет работать с отдельными объектами, которые вы контролируете, но я не могу понять, как вы бы это сделали с помощью List
. Это может гарантировать, что объекты, возвращаемые в этом списке, не будут дублироваться (по любым критериям, которые вы сочтете).