How do you assign a lambda to a variable in Java 8?
Asked Answered
C

3

61

Just playing with the new lambda and functional features in Java 8 and I'm not sure how to do this.

For example the following is valid:

    Map<String, Integer> map = new HashMap<>();
    map.put("A", 1);
    map.put("B", 2);
    map.put("C", 3);
    map.compute("A", (k, v) -> v == null ? 42 : v + 41));

but the following gives me syntax errors:

    BiFunction x = (k, v) -> v == null ? 42 : v + 41;
    map.compute("A", x);

Any ideas?

Cannon answered 20/2, 2014 at 21:31 Comment(1)
Please post the actual syntax errors.Similarity
H
52

You have forgotten the generics on your BiFunction:

public static void main(final String[] args) throws Exception {
    final Map<String, Integer> map = new HashMap<>();
    map.put("A", 1);
    map.put("B", 2);
    map.put("C", 3);
    final BiFunction<String, Integer, Integer> remapper = (k, v) -> v == null ? 42 : v + 41;
    map.compute("A", remapper);
}

Running:

PS C:\Users\Boris> java -version
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b120)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b62, mixed mode)
Hanuman answered 20/2, 2014 at 21:41 Comment(6)
Cool. I see - I need to be very explicit about that. When you look at the parameter type when looking at the map.compute method it just shows it as BiFunction alone.Cannon
Java 8 type inference is significantly improved from previous versions you still need to specify the generic types at the start of an expression for the compiler to work from. If you look at the Javadoc for Map you can see the required types.Hanuman
Note that "final" is not required. It compiles fine without that. Not sure if that's a bug or a feature.Cannon
@Cannon in previous versions of Java final was required for a local variable to be accessible in an anonymous class. In Java 8 this has changed, the requirement now is that the variable is "effectively final", i.e. if the compiler determines that the variable is not reassigned. So feature...Hanuman
Your example doesn't use remapper in an AIC or in a lambda, so it doesn't even need to be effectively final. You could remove final from the declaration and reassign remapper to something else later and it would still work.Radioactivity
@StuartMarks I tend to add final to all variables if possible - just an affectation. But yes - you are correct.Hanuman
S
4

As Boris The Spider points out, the specific problem you have is the generics. Depending on context, adding an explicit {} block around the lambda will help add clarity and may be required.

With that, you would get something like:

BiFunction<String, Integer, Integer> x = (String k, Integer v) -> {v == null ? 42 : v + 41};

It would be pretty helpful for future readers who have the same problem if you posted your syntax errors so they can be indexed.

This link has some additional examples that might help.

Similarity answered 20/2, 2014 at 21:38 Comment(1)
This isn't quite right - see my answer. BiFunction takes 3 types arguments.Hanuman
B
4

example of passing a lambda containing a method

YourClass myObject = new YourClass();

// first parameter, second parameter and return 
BiFunction<String, YourClass, String> YourFunction; 

YourFunction = (k, v) -> v == null ? "ERROR your class object is null" : defaultHandler("hello",myObject);

public String defaultHandler(String message, YourClass Object)
{
     //TODO ...

     return "";
}
Beamer answered 15/6, 2016 at 13:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.