Many form of Lambda expression in Java
General form: () -> {}
: in ‘()’ is parameter(s), in `{}’ is function
- complete form:
(int a, int b) -> {
System.out.println(a + b);
}
- without parameter type:
(a, b) -> {
System.out.println(a + b);
}
- without Parentness: where there is only 1 parameter:
value -> {
System.out.println(value);
}
- without Brace curly: if your function can be 1 liner
value -> System.out.println(value);
Where to use Lamdba expression in Java
- replace anonymous class
If we have interface like below:
public interface Tester{
public void test(String s);
}
When we need to implement it, we can use anonymous class:
Tester testerImp = new Tester(){
@Override
public void test(String s){
System.out.println(s);
}
};
then implements in the main method:
public class TestLambda{
public boolean verify(String s, Tester t){
return t.test(s);
}
public static void main(String[] args){
TestLambda obj = new TestLambda();
Tester testerImp = new Tester(){
@Override
public void test(String s){
System.out.println(s);
}
};
boolean result = obj.verify("Test Successful", testerImp);
System.out.println(result);
}
}
now we can use just 1 line lambda replace the testerImp
class:
public class TestLambda{
public boolean verify(String s, Tester t){
return t.test(s);
}
public static void main(String[] args){
TestLambda obj = new TestLambda();
boolean result = obj.verify("Test Successful", s -> System.out.println(s));
System.out.println(result);
}
}
-
Collection iteration
Please see Stream() explained with examples
-
with Predicate
Predicate is the java.util.function package with only 1 abstract method:
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
you implement logic in the this test()
method, and return true of false, then use it in the stream()
with lambda format, in following example, we define a predicate class that can be used to filter different Person
, here is the person class define:
public class Person{
public int age;
public String name;
public boolean isFemale;
//getter and setter, and constructor ignored
}
we can create predicate methods for filtering (you can define them in the Person
class)
public static Predicate<Person> isFemale(){
return e -> e.isFemale;
}
then you can implements the Predicate:
...
List<Person> persons = new ArrayList();
//add person into list
...
//add all the female person into new list
List<Person> females = persons.stream().filter(isFemale).collect(Collectors.toList());
Lambda is announymous function of Function
Where you can use lamdba, actually is using java.util.Function
interface. Function
has following type:
- BiFunction: 2 parameters and 1 return value.
-
Supplier: no parameter Supplier is kind of “next available” containter, eg, you have list of ports can user on server, when start multi thread applications, you can one-by-one (with lock) to get ports available from the list.
- Consumer: 1 parameter but no return value
- Predicate: 1 parameter and return value is boolean
- Operator: parameter and return value are same type and number
2 steps to use Function
- Define Function<T, R> T is paramter, R is return value.
- Apply R.apply
3 forms of Function
- Use class definition
public class getStringLength implements Function<String, Integer> {
public Integer apply(String string){
return string.length();
}
}
public void implement(){
Function<String, Integer> functionClass = new getStringLength();
System.out.println(functionClass.apply("length counter"));
}
- Use Annonymous Class
//Annonymous class
Function<String, Integer> getStringLength = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
};
System.out.println(getStringLength.apply("length counter"));
- Use Lamdba
Function<String, Integer> getStringLengthLamdba = (s) -> {return s.length();};
System.out.println(getStringLengthLamdba.apply("length counter"));
Use Supplier
for lazy inialization
Supplier can perform lazy initialization
public class SparkSubmitter {
private final SimpleSparkEtlFilWatcherConfig.SparkConfig sparkConfig;
private final Supplier<SparkLauncher> sparkLauncherSupplier;
public SparkSubmitter(SimpleSparkEtlFilWatcherConfig config){
this.sparkConfig = config.getSparkConfig();
this.sparkLauncherSupplier = SparkLauncher::new;
}
public CompletableFuture<String> process(SimpleSparkEtlFilWatcherConfig.ExtractConfig extractConfig, SimpleSparkEtlFilWatcherConfig.LoadConfig loadConfig){
SparkLauncher launcher = sparkLauncherSupplier.get();
}