как удалить по ID (deleteById(long id) и delete(Developer developer)

198
22 октября 2017, 19:53

Дана сущность Developer Необходимо реализовать консольное приложение со следующим функционалом:

  1. Создание разработчика
  2. Редактирование
  3. Получение данных (чтение)
  4. Удаление

В качестве хранилища использовать текстовый файл

Необходимо реализовать следующие классы

Developer - POJO класс, который содержит данные о разработчике и Класс DeveloperDAO - содержит методы для работы с текстовым файлом

Вопрос собственно в следующем как удалить разработчика по ID

Ранее использовал List и парсил файл и далее удалял с помощью методов ArrayList на что мне сказали что не должны использовать LIst Хранить в оперативке не получится при больших объёмах Все операции - исключительно чтение из файла и запись в файл (атомарно)

текст файла

1,Ivan,Petrov,PHP Developer,20000

2,Tatyana,Zimina,C++ Developer,40000

    public class Developer {
    private long id;
    private String firstName;
    private String lastName;
    private String position;
    private double salary;
    public Developer(long id, String firstName, String lastName, String position, double salary) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.position = position;
        this.salary = salary;
    }
    @Override
    public String toString() {
        return id + ", " + firstName + ", " + lastName + ", " + position + ", " + salary;
    }
    public Developer() {
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getPosition() {
        return lastName;
    }
    public void setPosition(String position) {
        this.position = position;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
}
   public class DeveloperDAO {
       public Developer save(Developer developer){
        developer.getId();
        developer.getFirstName();
        developer.getLastName();
        developer.getPosition();
        developer.getSalary();
        System.out.println(developer.toString());
        return developer;
    }
    public Developer getAll() {
        try {
            // find the file with the developer date
            File devFile = new File("test.txt");
            Scanner devScanner = new Scanner(devFile);
            while (devScanner.hasNext()) {
                Developer developer = new Developer();
                String nextLine = devScanner.nextLine();
                String[] devData = nextLine.split(",");
                developer.setId((Long.parseLong(devData[0])));
                developer.setFirstName(devData[1]);
                developer.setLastName(devData[2]);
                developer.setPosition(devData[3]);
                developer.setSalary(Double.parseDouble(devData[4]));
                System.out.println(developer.toString());
            }
            System.out.println();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void deleteById(Long id){
       // ???
    }
    public void delete(Developer developer){
       //????
    }

    public Developer getById(Long id) {
        try {
            // find the file with the developer date
            File devFile = new File("test.txt");
            Scanner devScanner = new Scanner(devFile);
            while (devScanner.hasNext()) {
                Developer developer = new Developer();
                String nextLine = devScanner.nextLine();
                String[] devData = nextLine.split(",");
                developer.setId((Long.parseLong(devData[0])));
                developer.setFirstName(devData[1]);
                developer.setLastName(devData[2]);
                developer.setPosition(devData[3]);
                developer.setSalary(Double.parseDouble(devData[4]));
                if (id != null && id == developer.getId()){
                    System.out.println(developer.toString());
                }
                return developer;
            }
        } catch (FileNotFoundException e) {
            System.out.println("File not found");
        }
        return null;
    }

    public void update(Developer developer) {
        Writer writer = null;
        String str = developer.toString();
        try {
            writer = new FileWriter("test.txt",true);
            writer.write(str);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Answer 1

Судя по всему, задача у Вас учебная. Поэтому не буду приводить рабочие куски кода, но обрисую, что надо делать.

Поскольку речь идёт о больших объёмах данных, которые теоретически могут не влезть в оперативную память, то нужно экономить память.

Для этого всего лишь следует читать файл построчно, держа в памяти только текущую строку. Точнее, держа только по одной сущности Developer. Прочитанную сущность как-то обрабатываем и, возможно, сохраняем обратно в файл.

Только есть одна тонкость. Если мы изменили (отредактировали) сущность, и записали обратно в файл - то из-за различного количества символов в текстовых представлениях исходной и отредактированной сущности мы можем испортить содержимое файла. При удалении сущности из середины файла - та же проблема.

Чтобы избежать проблемы, легче всего использовать следующий "финт ушами":

  1. читаем сущности из одного файла

  2. записываем сущности в другой файл

  3. удаляем исходный файл

  4. "другой" файл переименовываем в исходный файл

Для примера дам примерный псевдокод для операции удаления сущности из файла.

import java.io.*;
import java.util.*;
public static void deleteById(long delete_id)
{
  File source_file = new File("test.txt");
  File temporary_file = new File("temporary.txt");
  // открытие файла "source_file"
  // создание пустого файла "temporary_file"
  while ( /* пока есть ещё строки в "source_file" */ )
  {
    Developer developer;
    // читаем сущность из "source_file" в объект developer
    if ( developer.id != delete_id )
    {
      // записать сущность в "temporary_file"
    }
  }
  source_file.delete();  // удалить файл "source_file"
  temporary_file.renameTo(source_file);  // переименовать "temporary_file" в "source_file"
}

Что касается операции добавления сущности в файл, то есть два пути:

  1. Просто добавить в конец исходного файла запись о добавляемой сущности

  2. (Если задача требует уникальности всех ID) Прочитать исходный файл, проверить на наличие записи с таким же ID, как у добавляемой сущности. Если такая запись нашлась, генерируем исключение. Иначе - пишем в конец файла добавляемую сущность.

Здесь, в обоих случаях возня с дополнительным файлом не требуется.

Плюс, совет насчёт функции DeveloperDAO.getAll(). Поскольку держать в памяти весь список сущностей запрещается, то лучший вариант - предоставить "клиенту" возможность перечисления сущностей - и пусть он делает что угодно. Это можно сделать по-разному, например создать свой итератор, читающий файл, либо задействовать функциональный подход.

Для последнего (функционального) варианта функция getAll будет выглядеть как-то так:

import java.util.function.*;
// ...
public void getAll(Consumer<Developer> action)
{
  // открыть файл
  while ( /* пока есть строки в файле */ )
  {
    Developer developer;
    // прочитать сущность в объект "developer"
    action.accept(developer);
  }
}
// примеры использования
DeveloperDAO.getAll(developer -> System.out.println(developer.toString()));
List<Developer> devs = new ArrayList<>();
DeveloperDAO.getAll(developer -> { if ( developer.firstName.equals("Alex") ) devs.add(developer); });
READ ALSO
Не получается обратиться к базе данных на сервере

Не получается обратиться к базе данных на сервере

Проект vaadin+h2+hibernate+tomcat пытаюсь обратиться к базе данных, но на этапе конфигурации выдает ошибку

222
Как в hibernate использовать rowset из jdbc?

Как в hibernate использовать rowset из jdbc?

Возможно вопрос неправильный и я бы его не задал, если бы не нужно было через три дня сдавать задание - crud-приложение с пагинациейПо условию...

184
После форматирования XML файла в Eclipse не могу его распарсить

После форматирования XML файла в Eclipse не могу его распарсить

При открытии файла XML в редакторе Eclipse последний выводит его одной длинной строкойПосле форматирования(в ручную или с Ctrl+Shift+F, не важно) я не могу...

168