Variable assignment in lambda expression

2020-06-30 03:33发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

AtomicReference can be declared as final and used to hold a reference.