Lambda is an anonymous function. We can understand lambda expression as a piece of code that can be passed (passing code like data). We can write more concise and flexible code. As a more compact code style, the language expression ability of Java has been improved.
1. How to write Lambda expressions
MyInterface interface (provide show method):
public interface MyInterface { void show(); }
Test class:
public class MyTest { public static void main(String[] args) { // Lambda expression, jdk1 After 8, provide a syntax style. You can think of it as a form of anonymous inner class, which can be passed as a parameter //Anonymous Inner Class MyInterface myInterface = new MyInterface() { @Override public void show() { System.out.println("This is show method"); } }; //For the above anonymous inner class, we can use Lambda expression to simplify it MyInterface myInterface2 = () -> { System.out.println("This is show method"); }; } }
2. Next step abbreviation of lambda's expression
public class MyTest2 { public static void main(String[] args) { //Lambda expressions, syntax for //Introduce an arrow symbol - > // Arrow - > divides the Lambda expression into left and right parts // To the left of the arrow is the formal parameter list of the abstract method in the interface // To the right of the arrow is the concrete rewriting logic of the abstract method // Writing of anonymous inner class Comparator<Integer> comparator = new Comparator<Integer>() { @Override public int compare(Integer a, Integer b) { return a - b; } }; //First step abbreviation: Comparator<Integer> comparator2 = (Integer a, Integer b) -> { return a - b; }; //The data type of the formal parameter can be omitted because there are generic types that can infer the data type of the formal parameter Comparator<Integer> comparator3 = (a, b) -> { return a - b; }; //It can be simplified again //If your rewrite logic has only one line of code, {} return can be omitted Comparator<Integer> comparator4 = (a, b) -> a - b; } }
3. How to write Lambda expression when parameters are passed in anonymous inner class
Iiterface interface:
public interface Iinterface { int test(int num); }
Test class:
public class MyTest2 { public static void main(String[] args) { Iinterface iinterface = new Iinterface() { @Override public int test(int num) { return num + 10; } }; Lambda expression,It shortens the anonymous inner class if there is only one formal parameter ()It can be omitted Iinterface iinterface2 = x -> x += 10; } }
4. Anonymous inner classes are passed as parameters and Lambda expressions are passed as parameters
public class MyTest3 { public static void main(String[] args) { TreeSet<String> strings = new TreeSet<>(new Comparator<String>() { @Override public int compare(String a, String b) { return 0; } }); TreeSet<String> strings2 = new TreeSet<>((a, b) -> a.compareTo(b)); //You can choose alt+enter to replace it with an Lmabda expression TreeSet<String> strings3 = new TreeSet<>((a, b) -> a.compareTo(b)); } }
5. The definition of functional interface is: the interface that contains only one abstract method is called functional interface.
Use @ FunctionalInterface annotation on any functional interface to check whether it is a functional interface. Meanwhile, javadoc will also contain a declaration that the interface is a functional interface
If the following code is annotated, an error will be reported:
//@The functional interface will report an error if it is added public interface HeHe { void aa(); void bb(); }
Functional interface:
@FunctionalInterface //This annotation indicates that this is a functional interface public interface HaHa { void test(); }
Test class:
public class MyTest { public static void main(String[] args) { //Lambda expressions need the support of functional interfaces. In other words, only functional interfaces can be written using lambda // Functional interface: there is only one abstract method in the interface, and an annotation @ FunctionalInterface can detect whether the interface is a functional interface HeHe heHe = new HeHe() { @Override public void aa() { } @Override public void bb() { } }; HaHa haHa = new HaHa() { @Override public void test() { } }; HaHa haHa2 = () -> System.out.println("aaaa"); } }
6. Four core functional interfaces provided in Java
Functional interface | Parameter type | Return type | purpose |
Consumer<T> Consumer interface | T | void | Apply operation to object of type T |
Supplier<T> Supply type interface | nothing | T | Return an object of type T, package |
Function<T, R> Functional interface | T | R | Apply operation to object of type T |
Predicate < T > assertion interface | T | boolean | Determines whether an object of type T |
Other functional interfaces:
Functional interface | Parameter type | Return type | purpose |
BiFunction<T,U,R> | T U | R | Apply to parameters of type T, U |
UnaryOperator<T> (sub interface of Function) | T | T | An object of type T |
BinaryOperator<T> (sub interface of BiFunction) | T T | T | Perform a second pass on an object of type T |
BiConsumer<T,U> | T U | void | Apply to parameters of type T, U |
ToIntFunction<T> | T | int | Calculate int, long |
IntFunction<R> | int | R | The parameters are int, long |
7. Method reference:
Method reference: method reference is actually another way to write Lambda expressions,
When the operation to be passed to the Lambda body already has an implemented method, you can use the method reference
Note: the parameter list of the implementation abstract method must be consistent with the parameter list of the method reference method!
Method reference: use the operator "::" to separate the method name from the name of the object or class.
There are three main uses:
Object:: instance method
Class:: static method
Class:: instance method
public class MyTest { public static void main(String[] args) { Consumer<String> consumer = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }; consumer.accept("abc"); Consumer<String> consumer2 = s -> System.out.println(s); consumer2.accept("hello"); //Your rewriting logic system for the abstract method public void accept(String s) in the Consumer interface out. println(s) //Note: the abstract method accept(String s) has no return value and a parameter //Let's look at our rewriting logic //PrintStream out = System.out; //out.println("abc"); //The return value type and parameter list of the println("abc") called are consistent with the return value type and parameter list of the accept(String s) method. If there is such a coincidence, it can be abbreviated as the following instance object:: method Consumer<String> consumer3 = System.out::println; System.out.println("=========================="); BinaryOperator<Double> binaryOperator = new BinaryOperator<Double>() { @Override public Double apply(Double x, Double y) { return Math.max(x, y); } }; //First abbreviation BinaryOperator<Double> binaryOperator2 = (x, y) -> Math.max(x, y); //The final abbreviation, because there is a coincidence rewriting //Observation: the apply abstract method in BinaryOperator has a return value and two parameters //Observe our rewrite logic math max(x, y); The called Max method has a return value and two parameters, which can correspond to the apply abstract method //Final abbreviation, class name:: static method BinaryOperator<Double> binaryOperator3 = Math::max; System.out.println("=============================================="); Comparator<String> comparator = new Comparator<String>() { @Override public int compare(String a, String b) { //The first parameter serves as the caller, and the second parameter serves as the incoming value return a.compareTo(b); } }; //Step 1 abbreviation Comparator<String> comparator2 = (a, b) -> a.compareTo(b); //Final shorthand: the first parameter acts as the caller, and the second parameter acts as the incoming value Comparator<String> comparator3 = String::compareTo; System.out.println("========================================="); BiFunction<String, String, Boolean> biFunction = new BiFunction<String, String, Boolean>() { @Override public Boolean apply(String x, String y) { return x.equals(y); } }; BiFunction<String, String, Boolean> biFunction2 = (x, y) -> x.equals(y); //Final abbreviation BiFunction<String, String, Boolean> biFunction3 = String::equals; } }
8. Constructor reference:
Format: ClassName::new
Combined with functional interface, it is automatically compatible with methods in functional interface. The constructor reference can be assigned to the defined method, and the constructor parameter list should be consistent with the parameter list of the abstract method in the interface!
Student class:
public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
Test class:
public class MyTest2 { public static void main(String[] args) { Supplier<Student> supplier = new Supplier<Student>() { @Override public Student get() { return new Student(); } }; Supplier<Student> supplier2 = () -> new Student(); //Final shorthand observation: if the constructor can correspond to the return value and formal parameter list of the abstract method get() in the interface, you can use the constructor reference shorthand Supplier<Student> supplier3 = Student::new; System.out.println("=================================================="); BiFunction<String, Integer, Student> biFunction = new BiFunction<String, Integer, Student>() { @Override public Student apply(String name, Integer age) { return new Student(name, age); } }; Student wangwu = biFunction.apply("wangwu", 25); //First abbreviation BiFunction<String, Integer, Student> biFunction2 = (name, age) -> new Student(name, age); Student s0 = biFunction2.apply("lisi", 24); //Final abbreviation: BiFunction<String, Integer, Student> biFunction3 = Student::new; Student s = biFunction3.apply("Zhang San", 23); } }