This question already has an answer here :
From How to initialize field using lambda I determined I could do this:
return pushTwoValueCommand((TwoValueCommand) (a, b) -> a + b); // put parentheses around type to cast lambda expression
From @ernest_k I see I can also do this:
return pushTwoValueCommand((a, b) -> a + b);
(though I don't understand how that version works—don't I have to use a functional interface?? https://medium.freecodecamp.org/learn-these-4-things-and-working-with-lambda-expressions-b0ab36e0fffc )
EDIT
@AndrewTobilko 's answer does a good job of explaining why you can do this (without the cast). The type can be inferred from pushTwoValueCommand's method definition, as long as pushTwoValueCommand wasn't overloaded (multiple definitions of pushTwoValueCommand) in such a way that the compiler can't determine which function interface to use.
Best Practices using Java 8 Lambdas, Tips and best practices on using Java 8 lambdas and functional interfaces. Learn why Java requires local variables to be effectively final when used Even without it, your interface will be treated as functional as long as it has a compiler treats every variable as final, as long as it is assigned only once. In Java, lambda expressions are closures. As you have seen, a lambda expression can capture the value of a variable in the enclosing scope. To ensure that the captured value is well defined, there is an important restriction. In a lambda expression, you can only reference variables whose value doesn't change.
The problem is that (a, b) -> a + b
without context is ambiguous. It could be a BinaryOperator<Integer>
, BiFunction<Integer, Integer, Integer>
, TwoValueCommand
. It could also represent any other functional interface that defined a method like C method(A, B)
.
If you have pushTwoValueCommand
overloaded with conflicting functional interfaces, you will run into the problem of ambiguity mentioned above.
If there is one version of pushTwoValueCommand
, you can pass (a, b) -> a + b
in directly and you'll be fine.
Java Lambda Expressions, This means that they do not inherit any names from a To access variables in the enclosing class, use the keyword this . Because of this assignment statement, the variable� When you use an inner class, it creates a new scope. You can hide local variables from the enclosing scope by instantiating new local variables with the same names. You can also use the keyword this inside your inner class as a reference to its instance. However, lambda expressions work with enclosing scope.
Another approach is enabling the pushTwoValueCommand
method to accept a functional interface .
For this specific usecase, a BiFunction
(documentation ) is ideal. Your code could be rewritten as
<T> T pushTwoValueCommand(
final BiFunction<T, T, T> function,
final T right,
final T left) {
// Do something else, and then
return function.apply(right, left);
}
and used as
return pushTwoValueCommand((a, b) -> a + b, 1, 3);
Lambda Expressions (The Java™ Tutorials > Learning the Java , modify variables inside of Lambda expressions in a pinch with Java's Lambda Expressions in Java 8. One solution without Lambda : Java. Now, when we try to solve the above problem with lambda and stream, then we worry that updating the count variable inside our lambda. But, we cant update the field which is declared final: Java
Lambda Expressions in Java, As most of us are used to write code using Object Oriented… Now, instead of assigning a reference of an object to the variable, what will be decided by the access modifiers defined for the variable (not for the function). As a little bonus I also show the Java lambda syntax in other situations, such as with an ActionListener, and several “handler” examples, including when a lambda has multiple parameters. Java 8 Thread/Runnable lambda syntax. First, here’s the Java 8 lambda syntax for a Runnable, where I create a Runnable and pass it to a Thread:
Modifying Variables Inside Lambdas, "Lambda" or "anonymous" functions are simply the notion of functions without names. Java, starting with Java 8, introduced an implementation of lambda functions, In particular, when the lambda object is being assigned to a variable, that� Using a lambda-variable inside of another lambda requires the variable to be initialized -> before defining a recursive lambda you must define it with a foo-value using a local lambda-variable inside a lambda requires the variable to be final, thus it cannot be redefined -> use a class/ object variable for the lambda as it is initialized with a
Java Lambda Expressions. Lambda expressions are known to be , In a typical use case, a Java API defines an interface, sometimes described as a " callback ActionListener for the sole purpose of allocating it once at an invocation site, a user typically Lambda expressions close over values, not variables. Lambda expressions can use variables defined in an outer scope. We refer to these lambdas as capturing lambdas. They can capture static variables, instance variables, and local variables, but only local variables must be final or effectively final.
Comments Do you run into a problem when you just write return pushTwoValueCommand((a, b) -> a + b)
? pointed me in the right direction ... sorry, but then you are not asking a new question. You are basically saying, this is a duplicate question, a bit of different wording. It is ok for you to do still put up that different wording, but I still consider it ok, too, to close out as DUP then.@GhostCat Fair enough, and I recognized the fact that it's a duplicate when I made the original post, but the wording was different enough I felt like it would be useful to post. A google search was not pointing me in the right direction very quickly. I'm glad this question is linked to the other answers (which is why I posted them) but the word duplicate is pretty misleading. A note on duplicates: stackoverflow.com/questions/54965111/… If you let the method accept the actual type of functional interface (like I did in my answer), you'll be fine. but, at @ernest_k 's suggestion, I tried it without the type cast and it still works—how? because he assumed you were having an ambiguity issue (which could be a cause). In reality you just omit any interface specification when you're passing a lambda like these unless you absolutely need to. as a result of what andrew was suggesting @edmqkk no surprise. (a, b) -> a + b
is a valid instance of the type you need to pass in the method Wow, that's interesting—I would only need to specify the type if I had overloaded the pushTwoValueCommand method? That's surprising—it feels like everywhere else in Java you have to be so explicit, but you get a little bit of type inference in this one scenario? Weird—considering java doesn't even have an auto keyword or type inference from definitions. @edmqkk actually, Java does a lot of type inference (whenever it's possible and wise). Often, we are just not aware of it and take it for granted. interesting. I'll have to come back to this after I've spent some more time with Java. Thanks! @edmqkk using this approach, the compiler will also stop you from using incompatible data types, as you're using a "T" type everywhere.