Помогите пожалуйста написать метод update по аналогии с методом deleteById

Друзья, я очень долго вожусь с CRUD приложением. У меня есть правильно написанный метод deleteById:

public boolean deleteById(Integer integerId) {
    List<Skill> skills = getAllSkillsFromFile().stream().peek(skill -> {
        if (Objects.equals(skill.getId(), integerId)) {
            skill.setStatus(Status.DELETED);
        }
    }).collect(Collectors.toList());
    writeSkillsToFile(skills);
    return true;
}

}

Мне теперь нужно по аналогии с этим методом реализовать метод update. Нужно:

  1. Получить список всех skills (коллекцию скиллов).
  2. В это коллекции найти тот skill, который имеет такой же id как и skillToUpdate.
  3. Заменить это skill поля name и Status (enum)
  4. Обновленную коллекцию записать в файл
  5. Вернуть skillToUpdate

То как я делаю - это неправильно.


Ответы (2 шт):

Автор решения: Cipher
 public Skill update(Skill skillToUpdate) {
        for (int i = 0; i < skills.size(); i++) {
            if (skills.get(i).getSkillId() == skillToUpdate.getSkillId()) {
                skills.get(i).setName(skillToUpdate.getName());
                skills.get(i).setStatus(skillToUpdate.getStatus());
                break;
            }
        }

        saveSkillsToFile();

        return skillToUpdate;
    }

Можно сделать так вот) Не понятно что по архитектуре, но за основу можно взять)

→ Ссылка
Автор решения: Nowhere Man

Во-первых, метод deleteToUpdate написан не совсем правильно, так как он использует побочный эффект в методе Stream::peek, чтобы модифицировать текущую коллекцию, тогда как этот метод рекомендуется применять прежде всего для отладки:

Stream<T> peek(Consumer<? super T> action) ...
This is an intermediate operation.
...
API Note:
This method exists mainly to support debugging, where you want to see the elements as they flow past a certain point in a pipeline Parameters:
action - a non-interfering action to perform on the elements as they are consumed from the stream

Исправленный вариант мог бы выглядеть так (добавлена проверка текущего статуса, чтобы не было повторного удаления):

public boolean deleteById(Integer integerId) {
    List<Skill> allSkills = getAllSkillsFromFile();

    List<Skill> skillsToDelete = allSkills.stream()
        .filter(skill -> Objects.equals(skill.getId(), integerId)
                      && skill.getStatus() != Status.DELETED
        )
        .collect(Collectors.toList());

    skillsToDelete.forEach(skill -> skill.setStatus(Status.DELETED));

    if (!skillsToDelete.isEmpty()) {
        writeSkillsToFile(allSkills);
        return true;
    }

    return false; // id не найден, отмечать как удалённый нечего
}

Метод updateSkill можно написать по аналогии с предыдущим, в том числе имеет смысл возвращать булевое значение, указывающее, что коллекция/файл были модифицированы, а не входное значение update:

public boolean updateSkill(Skill update) {
    List<Skill> allSkills = getAllSkillsFromFile();

    Optional<Skill> skillToUpdate = allSkills.stream()
        .filter(skill -> Objects.equals(skill.getId(), update.getId()))
        .findFirst();

    skillToUpdate.ifPresent(skill -> {
        skill.setStatus(update.getStatus());
        skill.setName(update.getName());
        writeSkillsToFile(allSkills);
    });

    return skillToUpdate.isPresent();
}

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

→ Ссылка