New features in Java 8 - lambda expression - syntax

 

1. Basic syntax of lambda expressions

Because a lambda expression is an anonymous method, you don't have to care about the name of the method.

In fact, when designing lambda expressions, we don't need to care about what the return value is. There are only two parts we need to care about:

parameter   and   Method body

Parameter - > method body   Is the most basic syntax of lambda expressions. In the syntax, symbols are used  ->  Separate the parameter part from the method body part.

 

Parameter part: it must be consistent with the parameters of the method defined in the interface.

Method body: if the method defined in the interface has a return value, the result must be returned before the method ends.

@FunctionalInterface
interface Calculate {
   int calculate(int num1, int num2);
}
​
Calculate c = (int num1, int num2) -> { 
   return num1 + num2;
};

 

 

2. Syntax simplification of lambda expressions

In the above basic syntax, a concise implementation of an interface is realized by using lambda expression. However, the interface implemented in this way is not very concise. In fact, in the above code, there are still many places that can be omitted.

2.1 simplification of parameters

1. Because the number and type of parameters have been defined in the method of the interface, you can write the name of the parameter directly without writing the type of the parameter during implementation.

matters needing attention:
If you want to omit the type of a parameter, the type of each parameter must be omitted. Some parameter write types and some parameters do not appear.
@FunctionalInterface
interface Calculate {
   int calculate(int num1, int num2);
}
Calculate c = (n1, n2) -> {
   return n1 + n2;
};
@FunctionalInterface
interface Calculate {
   int calculate(int num);
}
Calculate c = n -> {
   return n * 2;
};

2. If there is only one parameter in the parameter list of the method, the parentheses can also be omitted.

@FunctionalInterface
interface Calculate {
    int calculate(int num);
}
Calculate c @Override = n -> {
    return n * 2;
};

 

2.2 simplification of method body

1. If the statement in the method body has only one sentence, the braces can be omitted.

@FunctionalInterface
interface Test {
   void show(String msg);
}
​
Test t = msg -> System.out.println(msg);
@FunctionalInterface
interface Calculate {
   int calculate(int num);
}
Calculate c = n -> n * 2;

2. If the only statement in the method body is a return statement, the return must be omitted as well as the braces.

@FunctionalInterface
interface Calculate {
    int calculate(int num);
}
Calculate c = n -> n * 2;

 

 

3. Method reference

  lambda The expression is to simplify the implementation of the interface lambda Do not appear too complex code in the implementation of. Too complex code can lead to poor readability of the code. Therefore, if you need a more complex implementation, you need to customize a method first, and then call this method directly.
  If in lambda The function to be implemented in the expression has been implemented in other methods. We don't need to re implement it. We can directly use an existing method. At this time, a simpler way is to use method reference and implement the specified interface with an existing method.

3.1. Common method reference

If the logic to implement an interface has been implemented in another method, you can directly reference the implemented method. At this time, you only need to make a simple method reference.

When referencing a method, you need to use the symbol::, write the body of the reference in front and the method of the reference in the back. Static methods use class references, and non static methods use object references.

Method reference also requires method parameters and return value types. Not all methods can be used as referenced methods. Only when the parameter and return value types of a method are consistent with the methods defined in the interface can a method be referenced.

Summary:
1. Static methods use class references, while non static methods use object references
2. Only methods whose parameters and return values are consistent with those defined in the interface can be referenced
public class FunctionReferences {
    public static void main(String[] args) {
        // Interface reference
        // 1. Use class to reference a static method
        CalculateTest test = FunctionTest::calculate;
        // 2. Because calculate2 is a private permission, it cannot be accessed outside the class or referenced by a method
        // CalculateTest test2 = FunctionTest::calculate2;
        // 3. Use an object to reference a non static method
        CalculateTest test3 = new FunctionTest()::calculate3;
        // Not all methods can be referenced. You must ensure that the parameters, return values and methods defined in the interface are completely consistent
        // CalculateTest test4 = FunctionTest::calculate4;
    }

}

class FunctionTest {
    public static int calculate(int a, int b) {
        if (a > b) {
            return a - b;
        }
        return b - a;
    }

    private static int calculate2(int a, int b) {
        return a - b;
    }

    public int calculate3(int x, int y) {
        return x - y;
    }

    public void calculate4(int a) {

    }
}

@FunctionalInterface
interface CalculateTest {
    int calculate(int a, int b);
}

3.2 reference of construction method

If the method in an interface is to obtain the of an object, you can directly reference the constructor of the class. Which constructor to refer to depends on the type and number of method parameters in the interface.

public class Test {
    public static void main(String[] args) {
        // 1. Because the get method in GetPerson is parameterless, the parameterless constructor in the Person class is referenced at this time
        GetPerson get = Person::new;

        // 2. Because the get method in GetPerson2 is parameterized, the reference is to the parameterized constructor in the Person class
        GetPerson2 get2 = Person::new;
    }
}

interface GetPerson {
    Person get();
}

interface GetPerson2 {
    Person get(String name, int age);
}

class Person {
    public Person() { }
    public Person(String name, int age) {

    }
}

3.3,   Reference to setter/getter method

If the parameter of a method in a functional interface is an object, you need to return the property value of an object. At this time, the implementation of this interface can be implemented by using the getter method reference of the object.

public class Test {
    public static void main(String[] args) {
        // 1. Because the interface method parameter at this time is a Person, and the return value is a Person attribute
        //    At this point, you can use the reference implementation of the getter method
        GetterTest test = Person::getName;
    }
}

interface GetterTest {
    String getName(Person person);
}

class Person {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Posted by Atari on Thu, 02 Dec 2021 20:49:45 -0800