Проблема при преобразовании старой школы, если использование в Optional.ifPresent () - PullRequest
0 голосов
/ 01 октября 2018

При преобразовании старой школы при использовании Optional.ifPresent я столкнулся с проблемой.Вот предыдущая версия кода.

State state = State.OK;
final Optional<Person> checkExistingPerson = checkIt();

if(checkExistingPerson.isPresent()) {
    Person person = checkExistingPerson.get();

    if("blah".equals(person.getName())) {
        state = State.DUPLICATE;
    } else {
        state = State.RESTORED;
    }

    return Member(person.getId(), state);
}

return Member(null, state);

А вот Optional.ifPresent использование

State state = State.OK;
final Optional<Person> checkExistingPerson = checkIt();

checkExistingPerson.ifPresent(person -> {

    if("blah".equals(person.getName())) {
        state = State.DUPLICATE;
    } else {
        state = State.NEW;
    }

    return Member(person.getId(), state);
});

return Member(null, state);

А также, вот скриншот, на котором IntelliJ заставляет меня изменить его.enter image description here

Как лучше всего использовать Optional в отношении моей проблемы?Спасибо всем!

Ответы [ 4 ]

0 голосов
/ 01 октября 2018

Вы не можете изменить значение локальной переменной из лямбда-выражения.Кроме того, ifPresent не может вернуть значение, так как его тип возвращаемого значения void.

Вместо этого вы должны использовать Optional.map, который преобразует объект, заключенный в Optional, если он присутствует:

return checkExistingPerson
    .map(person -> new Member(
            person.getId(), 
            "blah".equals(person.getName()) ? State.DUPLICATE : State.RESTORED))
    .orElse(new Member(null, State.OK));
0 голосов
/ 01 октября 2018

Во внутреннем методе вы не можете ссылаться на внешние переменные, если они не определены как окончательные, вы можете изменить свой метод следующим образом:

final Optional<Person> checkExistingPerson = checkIt();

checkExistingPerson.ifPresent(person -> {
    State state;
    if("blah".equals(person.getName())) {
        state = State.DUPLICATE;
    } else {
        state = State.NEW;
    }

    return Member(person.getId(), state);
});

return Member(null, State.OK); 
0 голосов
/ 01 октября 2018
  1. Внешние переменные внутри лямбды должны быть final.
  2. ifPresent принимает Consumer, поэтому не имеет возвращаемого значения,поэтому вы не можете использовать return Member(person.getId(), state); (также помните, что вы находитесь внутри лямбды, поэтому return не собирается выходить из вашего метода, а из лямбды).

map вместо этого принимает Function, который имеет возвращаемое значение, так что вы можете использовать его вместо ifPresent.

Вот как вы можете реорганизовать свой код,перемещая state внутри лямбды и используя map и orElseGet:

return checkExistingPerson.map(person -> {
    State state;

    if("blah".equals(person.getName())) {
        state = State.DUPLICATE;
    } else {
        state = State.NEW;
    }

    return Member(person.getId(), state);
})
.orElseGet(() -> Member(null, State.OK));
0 голосов
/ 01 октября 2018

Если вы обращаетесь к локальным переменным внутри лямбда-выражения, то переменные должны быть окончательными или эффективно окончательными, что означает, что их нельзя изменить здесь , вы также можете объявить переменные внутри лямбда-выражений.вопрос ifPresent примет Consumer в качестве аргумента, который не имеет возвращаемого типа, вы используете map, который примет Function и параметр в соответствии с @ Loris

...