Дана сущность Developer Необходимо реализовать консольное приложение со следующим функционалом:
В качестве хранилища использовать текстовый файл
Необходимо реализовать следующие классы
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();
}
}
}
Судя по всему, задача у Вас учебная. Поэтому не буду приводить рабочие куски кода, но обрисую, что надо делать.
Поскольку речь идёт о больших объёмах данных, которые теоретически могут не влезть в оперативную память, то нужно экономить память.
Для этого всего лишь следует читать файл построчно, держа в памяти только текущую строку. Точнее, держа только по одной сущности Developer. Прочитанную сущность как-то обрабатываем и, возможно, сохраняем обратно в файл.
Только есть одна тонкость. Если мы изменили (отредактировали) сущность, и записали обратно в файл - то из-за различного количества символов в текстовых представлениях исходной и отредактированной сущности мы можем испортить содержимое файла. При удалении сущности из середины файла - та же проблема.
Чтобы избежать проблемы, легче всего использовать следующий "финт ушами":
читаем сущности из одного файла
записываем сущности в другой файл
удаляем исходный файл
"другой" файл переименовываем в исходный файл
Для примера дам примерный псевдокод для операции удаления сущности из файла.
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"
}
Что касается операции добавления сущности в файл, то есть два пути:
Просто добавить в конец исходного файла запись о добавляемой сущности
(Если задача требует уникальности всех 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); });
Виртуальный выделенный сервер (VDS) становится отличным выбором
Проект vaadin+h2+hibernate+tomcat пытаюсь обратиться к базе данных, но на этапе конфигурации выдает ошибку
Возможно вопрос неправильный и я бы его не задал, если бы не нужно было через три дня сдавать задание - crud-приложение с пагинациейПо условию...
При открытии файла XML в редакторе Eclipse последний выводит его одной длинной строкойПосле форматирования(в ручную или с Ctrl+Shift+F, не важно) я не могу...