Lambda expressions can be assigned to variables and reused, but their filter conditions are fixed. Assign Java8 lambda expression to variable and reuse it
Therefore, if you want to change the filter condition, you may need to define a separate expression. For example A lambda expression that filters "only strings with a string length of 5", If you want a lambda expression that filters "only strings with a string length of 8", you can define two expressions as follows:
lengthFiveOrEight
//String length 5
final Predicate<String> lengthEqualFive = name -> name.length() == 5;
//String length 8
final Predicate<String> lengthEqualEight = name -> name.length() == 8;
It's okay if the conditions are always fixed, but if the application wants the flexibility to change the conditions, you may have to define as many expressions as there are.
If this condition (5 or 8 in this example) can be received as a parameter, such duplication can be avoided. For example, you can define the following method.
lengthEqualWith
Predicate<String> lengthEqualWith(final Integer expectsLength) {
return name -> name.length == expectsLength;
}
Instead of simply assigning a lambda expression to a variable, you pass an argument to a method that returns a lambda expression and apply that argument to the lambda expression. By passing expectsLength as a parameter when calling lengthEqualWith (), it is possible to change the conditions flexibly.
Try filtering using the list below.
final List<String> months =
Arrays.asList("January", "February", "March", "April", "May", "June", "July", "Augast", "September", "October", "November", "December");
LengthEqualWith (N) is applied as follows.
System.out.println("Length is 5");
List<String> result1 = months.stream().filter(lengthEqualWith(5)).collect(Collectors.toList());
result1.forEach(System.out::println);
System.out.println("Length is 8");
List<String> result2 = months.stream().filter(lengthEqualWith(8)).collect(Collectors.toList());
result2.forEach(System.out::println);
You will get the following (as expected) results:
Length is 5
March
April
Length is 8
February
November
December
This lambda expression looks for the expectsLength variable in scope, which seems to be called static scope (or syntactic scope). If the expectsLength variable is in scope (cached), the lambda expression uses that value.
In this example, the static scope is inside the lengthEqualWith () method. The expectsLength variable must be final, because lambda expressions can only access local variables in final.
Even if it's not declared final, it seems to work if the condition to be final is met (that is, if the variable is initialized and immutable).
However, Java needs to evaluate whether those conditions are met (it costs money), so caching or not caching these values may make a slight difference in performance. ..
Recommended Posts