lambda expressions
@FunctionalInterface
Annotation of functional interface
There can only be one abstract method in a functional interface, not only one method.
1. Basic use
2. Reference method
Method owner: method name
The owner of a static method is a class, and the owner of a common method is an object
package com.chen.lambda; /** * lambda Expression reference method */ public class Test { public static void main(String[] args) { //Reference static methods in this class ReturnOneParam returnOneParam = Test::doubleNum; int result = returnOneParam.method(20); System.out.println(result); //Reference non static methods in this class Test test = new Test(); ReturnOneParam returnOneParam1 = test::addTwo; int result1 = returnOneParam1.method(10); System.out.println(result1); //Reference static methods not in this class ReturnOneParam returnOneParam3 = Test1::treble; int result3 = returnOneParam3.method(20); System.out.println(result3); //Reference non static methods in this class Test1 test1 = new Test1(); ReturnOneParam returnOneParam2 = test1::addThree; int result2 = returnOneParam2.method(10); System.out.println(result2); } /** * lambda Requirements for using reference methods in the method body of expressions: * * Referenced methods and abstract methods in functional interfaces * 1,The return value type is consistent * 2,The parameter type and number are consistent */ public static int doubleNum(int a){ return 2*a; } public int addTwo(int a){ return a+2; } } /** * A functional interface with a return value and a parameter */ interface ReturnOneParam{ int method(int a); }
3. Create thread
package com.chen.lambda; /** * lambda The expression implements the run() method of the Runnable interface */ public class Test2 { public static void main(String[] args) { System.out.println(Thread.currentThread().getName()+" start"); new Thread(()->{ for (int i = 0; i < 20; i++) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"\t"+i); } },"lambda thread").start(); System.out.println(Thread.currentThread().getName()+" end"); } }
4. Operation set
1. Traversal set
package com.chen.lambda; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; public class Test3 { public static void main(String[] args) { List<String> list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); ConsumerImp c = new ConsumerImp(); /** * default void forEach(Consumer<? super T> action) { * Objects.requireNonNull(action); * for (T t : this) { * action.accept(t); * } * } */ list.forEach(c); } } /** * Consumer Is a functional interface */ class ConsumerImp implements Consumer{ @Override public void accept(Object o) { System.out.println(o); } }
Principle of simplification
- Consumer is a functional interface whose abstract method is accept (T)
- Each element traversed by the forEach() method is passed to the accept (T) method to perform an operation
- If we only need to output this element, that is, system. Out. Println (T)
- Both accept (T) and println (T) methods have no return value, only one parameter, and the parameter types are the same (here)
- So we refer to the println (T) method as the implementation of accept (T)
- The println (T) method is not a static method and needs to be called by an object of the PrintStream class
- out is just a static property of PrintStream class, so it is used to represent the owner of println (T) method, PrintStream class
[question] out is an attribute of PrintStream class, not an object! The static attribute is subordinate to the class. You can find the class through the static attribute? So you understand?
package com.chen.lambda; import java.util.ArrayList; import java.util.List; public class Test3 { public static void main(String[] args) { List<String> list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); //The simplified version does not even need to pass the printed content list.forEach(System.out::println); } }
2. Delete element
package com.chen.lambda; import java.util.ArrayList; import java.util.List; public class Test4 { public static void main(String[] args) { List<String> list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); list.removeIf((ele)->{ return ele.equals("b"); }); //simplify list.removeIf(ele->ele.equals("b")); list.forEach(System.out::println); } }
principle
-
Abstract method Boolean test (T) of functional interface Predicate
-
Pass in a parameter and return a Boolean value
-
realization:
Incoming element -- each element iterated by the iterator
Returns a Boolean value -- the equals() method, comparing each element of the iteration with the target element
/** * Primitive writing */ list.removeIf((ele)->{ return ele.equals("b"); }); /** * Simplified writing */ list.removeIf(ele->ele.equals("b"));
3. Element sorting
package com.chen.lambda; import java.util.ArrayList; import java.util.Comparator; import java.util.List; /** * 1,Method of passing in comparator * 2,Through lambda expression */ public class Test5 { public static void main(String[] args) { List<String> list = new ArrayList(); list.add("b"); list.add("c"); list.add("a"); list.add("d"); //list.sort(new MyComparator()); list.sort((o1,o2)->o1.compareTo(o2)); list.forEach(System.out::println); } } class MyComparator implements Comparator<String>{ @Override public int compare(String o1, String o2) { return o1.compareTo(o2); } }
5. Closure problem
The essence of a closure is a code fragment, which can also be understood as a reference to a code fragment. In java, anonymous inner classes are also an implementation of closures.
When accessing external variables in closures, the external variables must be final modified, and the virtual machine will automatically add the final keyword for us.
package com.chen.lambda; public class Test6 { public static void main(String[] args) { final int n = 10; A a = ()->System.out.println(n);; a.method(); //n++; } } /** * Define a functional interface with no return value and no parameters */ interface A{ void method(); }