Можно ли проводить сериализацию не объекта класса, а коллекции?
Есть код, где пытаюсь провести сериализацию List
, но значения листа не сохраняются в файл добавленный в пакет проекта, так же не проходит десериализация, на методе readObject
выпадает ошибка?
public void serialize(List > String < exitData) {
try {
FileOutputStream a = new FileOutputStream("DataExit.json");
ObjectOutputStream b = new ObjectOutputStream(a);
b.writeObject(exitData);
b.flush();
b.close();
a.close();
} catch (IOException i) {
i.printStackTrace();
}
}
public void deSerialize() {
try {
FileOutputStream a = new FileOutputStream("DataExit.json");
ObjectOutputStream b = new ObjectOutputStream(a);
exitDeserial = (ArrayList) b.readObject(); //?????
b.close();
a.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException j) {
System.out.println("List not found");
j.printStackTrace();
return;
}
for (String t: exitDeserial) {
System.out.println(t);
}
}
Можно сделать так:
String path = "D:\\list.obj";
List<Integer> list;
if (!new File(path).exists()) {
list = List.of(1, 2, 3, 4, 5);
try (final ObjectOutputStream ObjectOutputStream = new ObjectOutputStream(new FileOutputStream(path))) {
ObjectOutputStream.writeObject(list);
}
} else {
try (final FileInputStream FileOutputStream = new FileInputStream(path);
final ObjectInputStream ObjectInputStream = new ObjectInputStream(FileOutputStream)) {
list = (List) ObjectInputStream.readObject();
}
System.out.println(list);
}
Вывод:
[1, 2, 3, 4, 5]
Сразу вы не увидите вывода, так-как сначала будет запись объекта, а после уже когда файл существует, добавится в коллекцию.
Или вообще сделать отдельно класс для этого:
public final class Serialize {
private final String path;
private final File file;
private Object object;
public Serialize(final String path) {
this.path = path;
this.file = new File(path);
}
public void serialize(final Object object) {
try (final FileOutputStream FileOutputStream = new FileOutputStream(path);
final ObjectOutputStream ObjectOutputStream = new ObjectOutputStream(FileOutputStream)) {
ObjectOutputStream.writeObject(object);
} catch (final IOException io) {
//...логи ошибок
}
}
public Object deserialize() {
try (final FileInputStream FileOutputStream = new FileInputStream(path);
final ObjectInputStream ObjectInputStream = new ObjectInputStream(FileOutputStream)) {
object = ObjectInputStream.readObject();
} catch (final IOException | ClassNotFoundException ex) {
//...логи ошибок
}
return object;
}
public boolean is() {
return null != this.file && this.file.exists();
}
}
И уже использовать так:
final Serialize ser1 = new Serialize("D:\\list.obj"),
ser2 = new Serialize("D:\\str.str");
if (!ser1.is()) {
ser1.serialize(List.of(1, 2, 3, 4, 5));
}
List<Integer> list = (List<Integer>) ser1.deserialize();
System.out.println(list); // [1, 2, 3, 4, 5]
if (!ser2.is()) {
ser2.serialize("String");
}
String string = (String) ser2.deserialize();
System.out.println(string); // String
Мможно сделать сразу динамическое приведения к нужному типу, во время вызова deserialize
.
public <T> T deserialize() {
try (final FileInputStream FileOutputStream = new FileInputStream(path);
final ObjectInputStream ObjectInputStream = new ObjectInputStream(FileOutputStream)) {
final Object Object = ObjectInputStream.readObject();
final Class<?> Class = Object.getClass();
return (T) Class.cast(Object);
} catch (final IOException | ClassNotFoundException ex) {
//...логи ошибок
return null;
}
}
И можно уже будет использовать так:
final Serialize ser1 = new Serialize("D:\\list.obj"),
ser2 = new Serialize("D:\\str.str");
if (!ser1.is()) {
ser1.serialize(List.of(1, 2, 3, 4, 5));
}
List<Integer> list = ser1.deserialize();
System.out.println(list); // [1, 2, 3, 4, 5]
if (!ser2.is()) {
ser2.serialize("String");
}
String string = ser2.deserialize();
System.out.println(string); // String
Вывод аналогичный с вариантом выше.
Вы должны сериализовать объект. Да он может содержать в себе коллекции других сериализуемых объектов.
Все Ваши объекты должены реализовывать интерфейс Serializable
, и содержать в себе константу serialVersionUID
- уникальный идентификатор версии сериализованного класса. Чтоб объект мог быть десериализован, текущее значение в классе и в сериализованном объекте должны совпадать.
Схема такая:
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
...
private List<Document> documents;
private transient String secret; //данное поле не будет сериализовано
}
public class Document implements Serializable {
private static final long serialVersionUID = 1L;
...
}
подробно можете посмотреть здесь https://javarush.ru/groups/posts/2022-serializacija-i-deserializacija-v-java
можно использовать обертку для сериализации/десериализации
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class test {
public static void main(String[] args) throws IOException {
ArrayList<SUser> objects = new ArrayList<SUser>(){{
add(new SUser("s1", "s2"));
add(new SUser("s1", "s2"));
}};
byte[] bytes = new ObjectMapper().writeValueAsBytes(objects);
ObjectMapper objectMapper = new ObjectMapper();
List<SUser> sUsers = objectMapper.readValue(bytes, new TypeReference<List<SUser>>() {
});
for (SUser sUser : sUsers) {
System.out.println(sUser.getField1() + " " + sUser.getField2());
}
}
}
////////////////////////////////////////
import java.io.Serializable;
public class SUser implements Serializable {
private String field1;
private String field2;
public SUser() {
}
public SUser(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
public String getField1() {
return field1;
}
public String getField2() {
return field2;
}
}
///////////////////////////////////////////////
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version> //check for new version
</dependency>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Проблема возникла со словами после знака присвоения
Программно создаю кнопки, но недавно понадобилось делать отступ вниз от каждой кнопкиЯ так понял надо задать layout_marginbottom
товарищиОбъясните, кто нибудь, какой JDK нужен сейчас, для разработки под Android? В интернетах у каждого свое мнение