Вывод объектов из файла
Изучаю ввод/вывод данных, но не совсем понятно(а может и совсем не понятно) как работать с объектами. Возможно кто-то подскажет и объяснит как это работает? Есть файл в котором записаны некоторые объекты(точнее наверное их поля). Как на примере:
name : "name"
secondName : "secondName"
heigtn : 180
age : 30
name : "name2"
secondName : "secondName2"
heigtn : 185
age : 32
name : "name3"
secondName : "secondName3"
heigtn : 190
age : 20
Стоит задача вывести все эти объекты(поля) в наш код, произвести с ними разные операции (по типу: кто выше, кто старше и т.п.) и результат записать в другой файл.
У меня проблема с выводом и вводом объектов! Все мои попытки - приводят к Exception разного типа. Возможно, кто-то научит и объяснит как правильно поступать в этом случае, и покажет на моем примере как это делать, потому что в интернете не нашел примеров похожих на мой случай или же их не понял.
Если это поможет делу - то я делал класс с конструктором для этих объектов и имплементировал Serializable.
Ответы (1 шт):
Предположим, имеется некий класс Person со строковыми полями name, secondName и целочисленными полями height, age, и текстовый файл указанного формата. Признаком конца объекта в файле служит пустая строка.
Далее, прочитанные объекты будут добавляться в соответствующий список List<Person> persons.
Итак, начинаем читать файл построчно -- для простоты, при помощи сканера Scanner::nextLine. Заводим несколько переменных, аналогичных полям объекта. Если строка непустая, разбиваем её по "\\s*:\\s*" (двоеточие с опциональными пробелами вокруг него) на пару "ключ - значение", и в зависимости от ключа запоминаем значение в соответствующей переменной при помощи оператора switch.
Как только обнаружена пустая строка (нашли конец объекта), создаем новый экземпляр с известными полями и добавляем её в коллекцию (список).
Примерная реализация в виде метода, принимающего имя файла и возвращающего список объектов:
public static List<Person> readPersons(String fileName) throws IOException {
Scanner scan = new Scanner(new File(fileName));
List<Person> persons = new ArrayList<>();
String name = null, secondName = null;
int age = 0, height = 0;
while (scan.hasNextLine()) {
// читаем строку, удаляя пробелы из её начала и конца
String line = scan.nextLine().trim();
if (line.isEmpty()) { // нашли пустую строку конец объекта
if (name != null && secondName != null && age > 0 && height > 0) {
// все поля прочитаны, создаем и добавляем экземпляр
persons.add(new Person(name, secondName, age, height));
// "сброс" полей
name = secondName = null;
age = height = 0;
}
continue;
}
// обработка отдельных полей
// разбиваем по двоеточию на пару ключ - значение
String[] keyValue = line.split("\\s*:\\s*");
switch (keyValue[0]) {
"name" -> name = keyValue[1];
"secondName" -> secondName = keyValue[1];
"age" -> age = Integer.parseInt(keyValue[1]);
"height" -> height = Integer.parseInt(keyValue[1]);
default -> System.out.println("Нашли неизвестное поле '" + keyValue[0] + "'");
}
}
return persons;
}
Возможно, понадобится дополнительно убрать пару кавычек из строковых значений:
public static stripQuotes(String str) {
return str == null || str.length() < 2
? str
: str.startsWith("\"") && str.endsWith("\"")
? str.substring(1, str.length() - 1)
: str;
}
тогда его придётся вызвать так:
switch (keyValue[0]) {
"name" -> name = stripQuotes(keyValue[1]);
"secondName" -> secondName = stripQuotes(keyValue[1]);