1. Lambda
1.1 general
Lambda expression is a function without name, which can also be called closure. It is the most important new feature released by Java 8. It is essentially an anonymous inner class or a piece of code that can be passed
And the arrow function
1.2 why use Lambda expressions
Lambda expression is a short form of anonymous inner class, which makes the program simpler and clearer, and improves the programming efficiency
1.3 comparison with anonymous inner classes
//2 anonymous inner class forEach(arr,new Array(){ public void m1(int i){ System.out.println(i +"-===-"); } });
//3Lambda expression forEach(arr,(i)->System.out.println(i+1+"+++"));
1.4 grammatical structure
Optional type declaration: there is no need to declare parameter types, and the compiler can uniformly identify parameter values
Optional parameter parentheses: one parameter does not need to define parentheses, but multiple parameters need to define parentheses
Optional curly braces: if the body contains a statement, curly braces are not required
If you don't write {} return, you can't write parentheses
Optional return keyword: if the body has only one expression return value, the compiler will automatically return the value. Curly braces need to indicate that the expression returns a value
If there is only one statement and it is a return value statement, you can not write return or {}
If you write {}, you must write return and;
If there are multiple statements, you must write {} return and;
1.5 cases
1 does not require parameters, and the return value is 5
()->5
2 receives a parameter (numeric type) and returns twice its value
x->x*2
3 receive two parameters (numbers) and return their difference
(x,y)->x-y
1.6 practice
package day_27text; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; public class Text02 { public static void main(String[] args) { List<Integer>list = new ArrayList<Integer>(); list.add(1); list.add(2); list.add(3); //Conventional writing //for(Integer integer :list){ //System.err.println(integer); //} //Anonymous inner class writing //list.forEach(new Consumer<Integer>(){ //public void accept(Integer t){ //System.out.println(t); //} //}); //Lambda writing list.forEach(x->System.out.println(x)); } }
package day_27text; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class Text03 { public static void main(String[] args) { List<Integer>list = new ArrayList<Integer>(); list.add(11); list.add(2); list.add(3); //Cillections.sort(list,new Comparator<Integer>(){ //public int compare(Inreger o1,Integer o2){ //return o2 - o1; //} //}); Collections.sort(list,(x,y) -> y - x); System.out.println(list); } } class B{ public boolean equals(Object obj){ return false; } }
2. Functional interface
2.1 introduction
Expected Functional Interface
Its essence is an interface with only one abstract method, but it can have multiple non abstract methods
The core goal is to provide better support for the use of Lambda expression and further achieve the goal of functional programming. The programming efficiency can be greatly improved by using functional programming
It can be implicitly converted to a Lambda expression
2.2 features
A functional interface is an interface that formulates only one abstract method
Can contain one or more static or default methods
The special annotation, namely @ Functional Interface, checks whether it is a Functional Interface or not
If there are two or more abstract methods, they cannot be used as functional interfaces, and the @ Functional Interface annotation cannot be added
If there is only one abstract method, the @ Functional Interface annotation can be used as a Functional Interface with or without it
2.3 code implementation
2.3.1 no participation
public class FunInterface_01 { // Custom static method to receive interface object public static void call(MyFunctionInter func) { // Calling member methods within an interface func.printMessage(); } public static void main(String[] args) { // The first call: directly call the custom call method and pass in the function FunInterface_01.call(() -> { System.out.println("HelloWorld!!!"); }); // The second call: first create a function object, similar to the internal class object that implements the interface MyFunctionInter inter = () -> { System.out.println("HelloWorld2!!!!"); }; // Call the method of this implementation inter.printMessage(); } } // Functional interface @FunctionalInterface interface MyFunctionInter { void printMessage(); }
2.3.2 with reference
public class FunInterface_02 { // Custom static method to receive interface object public static void call(MyFunctionInter_02 func, String message) { // Calling member methods within an interface func.printMessage(message); } public static void main(String[] args) { // Call the data to be passed String message = "Parametric functional interface call!!!"; // The first call: directly call the custom call method, pass in the function, and pass in the data FunInterface_02.call((str) -> { System.out.println(str); }, message); // The second call: first create a function object, similar to the internal class object that implements the interface MyFunctionInter_02 inter = (str) -> { System.out.println(str); }; // Call the method of this implementation inter.printMessage(message); } } // Functional interface @FunctionalInterface interface MyFunctionInter_02 { void printMessage(String message); }
2.4 JDK comes with common functional interfaces
2.4.1 supplier < T > interface
The supplier < T > interface represents the result supplier, so it has a return value and can obtain data
There is a get method for getting data
public class _03_JdkOwn_01 { private static String getResult(Supplier<String> function) { return function.get(); } public static void main(String[] args) { // 1 String before = "Zhang San"; String after = "Hello"; // Concatenate two strings System.out.println(getResult(() -> before + after)); // 2 / / create a Supplier container and declare it as_ 03_JdkOwn type // At this time, the construction method of the object is not called, that is, the object is not created Supplier<_03_JdkOwn_01> sup = _03_JdkOwn_01::new; _03_JdkOwn_01 jo1 = sup.get(); _03_JdkOwn_01 jo2 = sup.get(); } public _03_JdkOwn_01() { System.out.println("The construction method is executed"); } }
2.4.2consumer < T > interface
Consumer < T > interface consumer interface, so no return value is required
There is an accept(T) method, which is used to perform consumption operations. You can do any operation on a given parameter t
public class _04_JdkOwn_02 { private static void consumeResult(Consumer<String> function, String message) { function.accept(message); } public static void main(String[] args) { // Parameters passed String message = "Consume some content!!!"; // Call method consumeResult(result -> { System.out.println(result); }, message); } }
2.4.3 function < T, R > interface
The function < T.R > interface represents a function that receives a parameter and generates a result
As the name suggests, it is a function operation
There is a happy (T) method. There is no specific operation in the Function. The specific operation needs to be specified for it. Therefore, the result of the specific return value of apply depends on the incoming Lambda expression
public class _05_JdkOwn_03 { // Function < parameter, return value > public static void convertType(Function<String, Integer> function, String str) { int num = function.apply(str); System.out.println(num); } public static void main(String[] args) { // Parameters passed String str = "123"; // S indicates that parameters need to be passed. You can also write (s) convertType(s -> { int sInt = Integer.parseInt(s); return sInt; }, str); } }
2.4.4 predict < T > interface
Predicate < T > interface assertion interface
Just make some judgments, and the return value is boolean
There is a boolean test(T) method to verify whether the incoming data meets the judgment conditions and return the boolean type
public class _06_JdkOwn_04 { // Custom method, and Predicate receives String type public static void call(Predicate<String> predicate, String isOKMessage) { boolean isOK = predicate.test(isOKMessage); System.out.println("isOK Yes:" + isOK); } public static void main(String[] args) { // Parameters passed in String input = "ok"; call((String message) -> { // Case insensitive comparison. If it is ok, it returns true; otherwise, it returns false if (message.equalsIgnoreCase("ok")) { return true; } return false; }, input); } }
3. Method reference and constructor call
2.5 object call object
package day_27text03; import java.util.function.Supplier; /** * Object reference:: member method name * * Requirement: you need to select the corresponding functional interface according to the input and output parameters of the calling method * * @author Learn bald Zhang *@Date 2021 3:15:19 am, November 3 */ public class Text01 { public static void main(String[] args) { Integer i1 = new Integer(123); // Conventional lambda writing Supplier<String> su = () -> i1.toString(); System.out.println(su.get()); // Method reference writing su = i1::toString; System.out.println(su.get()); } }
2.6 class name calling static
package day_27text03; import java.util.function.BiFunction; import java.util.function.Function; /** *Class name: static * * @author Learn bald Zhang *@Date 2021 3:17:09 am, November 3 */ public class Text02 { public static void main(String[] args) { Function<String, Integer> fun = Integer::parseInt; System.out.println(fun.apply("123")); fun = new Function<String, Integer>() { @Override public Integer apply(String t) { // TODO Auto-generated method stub return null; } }; fun = x -> Integer.parseInt(x); fun = Integer::parseInt; // The first two are input parameters and the third is return value BiFunction<Integer, Integer, Integer> bif = Integer::max; System.out.println(bif.apply(123, 323)); test((B x) -> System.out.println(x)); } public static void test(A a) { } } interface A { public void m1(B b); } class B { }
2.7 class name calling object
package day_27text03; import java.util.function.BiPredicate; /** * Class name: member method name * * @author Learn bald Zhang *@Date 2021 3:22:42 am, November 3 */ public class Text03 { public static void main(String[] args) { BiPredicate<String, String> bp = String::equals; System.out.println(bp.test("abc", "abc")); } }
2.8 construction method call
package day_27text; import java.util.function.Function; import java.util.function.Supplier; public class Text04 { public static void main(String[] args) { //Nonparametric structure Supplier<Object> objSi = Object::new; System.out.println(objSi.get()); //Parametric structure Function<String,Integer> function = Integer::new; System.out.println(function.apply("123")); //new Integer("123"); } }
2.9 array reference
package day_27text; import java.util.function.Function; public class Text05 { public static void main(String[] args) { Function<Integer,Integer[]>function = Integer[]::new; Integer[] arr =function.apply(10); for(Integer integer:arr){ System.out.println(integer); } } }
4.Stream API
4.1 concept description
Data channel, pipeline, used to operate the element sequence generated by data source (set, array, etc.)
Collection is about data, and flow is about computation
That is, a set of API s used to process arrays and collections
4.2 features
Stream is not a data structure and has no internal storage. It will not store elements by itself
Streams do not change the source object. Instead, they return a new Stream that holds the result
Stream operations are delayed. This means that they wait until the results are needed
Index access is not supported
Delay calculation
Support parallelism
It is easy to generate data or collections
Support filtering, searching, conversion, summary, aggregation and other operations
4.3 application scenarios
Stream computing requires delayed computing and more convenient parallel computing
More flexible and concise collection processing scenarios
4.4 code implementation
4.4.1 description of operation mechanism
Stream is divided into source, intermediate operation and termination operation
The source of a stream can be an array, a collection, a generator method, an I/O channel, and so on
A stream can have zero or more intermediate operations. Each intermediate operation will return a new stream for the next operation. A stream will only have one termination operation
Intermediate operations are also called transformation operators
Only when a Stream encounters a termination operation, its data source will start to perform a traversal operation
The termination operation is also called action operator action
Because the return value of the action operator is no longer stream, the calculation is terminated
Only when we encounter the action operator can we really calculate
4.4.2 method of creating flow
package day_27text04; import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream; /** * Generate flow * * @author Learn bald Zhang *@Date 2021 3:37:07 am, November 3 */ public class Text01 { public static void main(String[] args) { // 1 convert array to stream String[] strings = { "q", "w", "e", "r" }; Stream<String> stream1 = Stream.of(strings); // 2 through set // Arrays.asList: convert arrays to collections List<String> list = Arrays.asList(strings); stream1 = list.stream(); // 3. Create through generate of Stream // However, it is an infinite stream (infinite), so it is often used in combination with limit to limit the maximum number // The generate parameter is a Supplier, and the Supplier has a get method to get data // The return value of the get method will be saved to the stream as data. The following program means that the data in the stream is 1 Stream<Integer> stream2 = Stream.generate(()->1); // limit is an intermediate operation that sets the maximum number of streams // forEach traversal is to terminate the operation stream2.limit(5).forEach(x->System.out.println(x) ); // 4 through String.iterate // Ditto, infinite flow // Parameter 1 is the starting value, parameter 2 is function, with parameters and return values // x+2 equals two steps for (int i = 1; true; I + = 2) Stream<Integer> stream3 = Stream.iterate(1, x->x+2); stream3.limit(10).forEach(x->System.out.println(x)); // 5 API of existing classes String string = "abc"; IntStream chars = string.chars(); chars.forEach(x->System.out.println(x)); } }