Вывод объектов из файла

Изучаю ввод/вывод данных, но не совсем понятно(а может и совсем не понятно) как работать с объектами. Возможно кто-то подскажет и объяснит как это работает? Есть файл в котором записаны некоторые объекты(точнее наверное их поля). Как на примере:

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 шт):

Автор решения: Nowhere Man

Предположим, имеется некий класс 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]);

→ Ссылка