Возврат с карты после лучшего способа фильтрации

#java #spring-boot #java-stream

#java #весенняя загрузка #java-поток

Вопрос:

здравствуйте, у меня есть эта функция setanimalhappy в моей программе Zoo, но я не думаю, что она хорошо написана, я думаю, что код после возврата является дополнением, он бесполезен

(return personRepository.save(person).getRecordList().parallelStream() .filter(record1 -> record1.getId().equals(animalRecord.getId())) .findFirst().orElseThrow(RecordException::new); }) .orElseThrow(PersonException::new);)

получить человека -> найти запись в списке записей -> обновить значение, сохранить в списке записей -> вернуть отредактированную запись

как я могу вернуть record1 из map во внешнюю функцию или улучшить этот код?

 @PutMapping("/{id}/animalhappy")
@ResponseBody
public Record SetAnimalHappy(@PathVariable String id, @RequestBody Record animalRecord) {

    return personRepository.findById(id)
            .map(person -> {
                person.getRecordList().parallelStream()
                        .filter(record1 -> record1.getId().equals(animalRecord.getId()))
                        .findFirst()
                        .map(record1 -> {
                            record1.getAnimalStatus().setHappy(true);
                                    return record1;
                                }
                        ).orElseThrow(RecordException::new);

                personRepository.save(person);

                return personRepository.save(person).getRecordList().parallelStream()
                        .filter(record1 -> record1.getId().equals(animalRecord.getId()))
                        .findFirst().orElseThrow(RecordException::new);
            })
            .orElseThrow(PersonException::new);
}
 

Комментарии:

1. CrudRepository::findById возвращает Optional значение, которое может быть пустым, и, следовательно, это приведет PersonException к. Я думаю, что это технически правильно.

2. Просто примечание: переименовать Record во что-то конкретное, потому что java 14 представила записи и Record является их суперклассом.

Ответ №1:

Похоже, вам здесь не нужно #map , как если Optional бы s были пустыми, вы хотите, чтобы создавались исключения:

 // this should probably live in the service layer instead of the controller layer:
public Record setAnimalHappy(String id, Record animalRecord) {
    Person person = personRepository
        .findById(id)
        .orElseThrow(PersonException::new);
    // the following might be replaced by recordService.findById(animalRecord.getId()),
    // while making sure the returned record belongs to `person`:
    Record record = person
        .getRecordList()
        .stream() // don't use parallel streams (unless you know what you're doing)
        .filter(record -> record.getId().equals(animalRecord.getId()))
        .findFirst()
        .orElseThrow(RecordException::new);
    // not 100% sure the 2 following lines behave the way you'd expect:
    record.getAnimalStatus().setHappy(true);
    personRepository.save(person);
    return record;
}
 

Помимо бизнес-логики, что-то в этом роде может быть, возможно, более читаемым.

Легко потеряться в обратных вызовах при входе в мир функционального программирования. Одно правило, которому я склонен следовать, — «не использовать -> { « (многострочные лямбда-выражения): либо реорганизуйте свой код (как в приведенном выше примере), либо используйте дополнительные функции для улучшения читаемости.

Интересное чтение по теме: https://dzone.com/articles/functional-programming-patterns-with-java-8 .

Комментарии:

1. Не уверен, знает ли OP, что он делает. Ответ явно более читабелен, но CrudRepository::save может содержать некоторую бизнес-логику или преобразование Record (возможно, в будущем). CrudRepository::save возвращает обновленный объект, поэтому я думаю, что извлечение обновленной записи и отправка ее обратно клиенту имело бы смысл, чтобы избежать каких-либо будущих сбоев.

2. Большая часть кода должна находиться на уровне сервиса, но, к сожалению, он находится в контроллере.

3. @AniketSahrawat да, точно, я согласен, отсюда и мой комментарий в коде. Я не хотел углубляться в это, поскольку вопрос был больше о удобочитаемости (если я правильно понял). Но обновление record при сохранении person действительно выглядит немного хитроумным.

4. Я добавил это (получить person -> найти запись в списке записей -> обновить значение, сохранить в списке записей -> вернуть отредактированную запись) для лучшего понимания, я новичок в ООП, и я узнаю, есть ли у вас лучший способ написания кода, поэтому я был бы признателен