Как я могу вернуть логическое значение, используя Optional.ifPresent - PullRequest
1 голос
/ 01 июля 2019

У меня есть некоторые проблемы с использованием оператора Optional.ifPresent. Я хотел бы уменьшить количество NullPointerExceptions, поэтому я решил использовать Optional значения.

Также я стараюсь избегать лестничных от if заявлений против паттерна.

Итак, я реализовал Optional.isPresent оператор. Но это не совсем то, что я ожидал.

Пожалуйста, посмотрите на эти списки:

Это часть моего сервиса:

    if (getAllComputerProducers().isPresent()) {
        if (isComputerProducerAlreadyExist(computerProducer))
            return new ResponseEntity<>(HttpStatus.CONFLICT);
    }

    computerProducerRepository.save(computerProducer);
    return new ResponseEntity<>(HttpStatus.CREATED);

getAllComputerProducers функция выглядит так:

private Optional<List<ComputerProducer>> getAllComputerProducers() {
    return Optional.ofNullable(computerProducerRepository.findAll());
}

Как видите, эта функция возвращает Optional из List.

Функция isComputerProducerAlreadyExist реализована так:

private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer) {
    return getAllComputerProducers()
            .get()
            .stream()
            .anyMatch(producer -> producer.getProducerName()
                    .equalsIgnoreCase(computerProducer.getProducerName()));
}

Это так много кода, и я считаю, что это можно сделать проще. Моя цель - сократить код до одной строковой команды, например:

getAllCimputerProducers().ifPresent(***and-here-some-anyMatch-boolean-function***)

но я не могу вставить туда функцию, которая что-то возвращает. Как я могу это сделать?

Привет всем:)

Ответы [ 3 ]

1 голос
/ 01 июля 2019

Вы можете попробовать что-то вроде

private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
    return this.getAllComputerProducers()
            .map((List<ComputerProducer> computerProducers) -> computerProducers.stream()
                    .anyMatch(producer -> producer.getProducerName().equalsIgnoreCase(computerProducer.getProducerName())))
            .orElse(Boolean.FALSE);
}

Или вместо загрузки всех производителей компьютеров загружать только тех, кто использует его имя.

private boolean isComputerProducerAlreadyExist(ComputerProducer computerProducer){
    return computerProducerRepository.findByName(computerProducer.getProducerName()).isEmpty();
}

И, насколько мне известно, Spring поддерживает также«Существующие» методы для репозиториев без необходимости загрузки сущности.

0 голосов
/ 01 июля 2019

Вы можете передать computerProducer.getProducerName() в хранилище, чтобы получить существующую запись. Имя метода будет 'findByProducerName(String producerName)', если имя производителя имеет уникальное ограничение, тип возвращаемого значения будет Optional<ComputerProducer>, иначе Optional<List<ComputerProducer>>. Однако JPA возвращает пустой список вместо нуля, поэтому необязательный список не требуется.

0 голосов
/ 01 июля 2019

Следующее должно работать, но у меня нет ничего для его компиляции.

Predicate<ComputerProducer> cpPredicate = producer -> producer.getProducerName().equalsIgnoreCase(computerProducer.getProducerName());

boolean compProdExists = getAllCimputerProducers().map(list -> list.stream()
                                                                   .filter(cpPredicate)
                                                                   .findFirst()))
                                                  .isPresent();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...