I have the following fragment of code:
SomeClass someClass;
switch (type) {
case FIRST:
someClass = new SomeClass();
break;
case SECOND:
OptionalLong optional = findSomeOptional();
optional.ifPresent(value -> someClass = new SomeClass(value));
}
And I'm trying to assign new object to someClass reference in lambda expresion but then I've got error message: "variable used in lambda should be effectively final".
When I add final to declaration of someClass I got another error "cannot assign value to final variable"
So how can I smartly deal with such assigment in lamdas?
The simple answer is you cannot assign local variables from upper levels in lambda expressions.
Either, you turn your variable into an instance member, or use an simple if statement:
SomeClass someClass;
switch (type) {
case FIRST:
someClass = new SomeClass();
break;
case SECOND:
OptionalLong optional = findSomeOptional();
if(optional.isPresent()) {
someClass = new SomeClass(optional.getAsLong());
}
}
The last option would be to use an AtomicReference
.
Do you have to use an OptionalLong
, or can you use an Optional<Long>
?
An appropriate idiom for what you want to do is someClass = optional.map(SomeClass::new).orElse(someClass)
. However, OptionalLong
doesn't have a map(LongFunction)
method, for some reason.
AtomicReference can be declared as final and used to hold a reference.