catalogue
2. Use Supplier to generate objects
3. Take Supplier as the parameter of the method
1. Use the Consumer object directly
3. Use Consumer as the parameter
1. test() method demonstration
6. Application example of predict
1. Method demonstration: apply()
2. BinaryOperator interface as method parameter
3. Demonstration of static methods
Parameters of the method used by UnaryOperator
7, Summary of common functional interfaces
Java 8 functional interface
Interface | parameter | return | chinese | example |
Supplier | None | T | Provider | Create objects using factory methods |
Consumer | T | None | consumer | Consume one data, no return |
Predicate | T | boolean | Judgment / predicate | Test the specified conditions |
Function | T | R | function | Get another parameter value from one parameter |
1, Supplier interface
The Supplier interface represents the provider of a result.
The Supplier interface is used to generate data. The type of data is given by generic parameters, and the return value is obtained by using the get() method.
The source code of the interface is as follows:
@FunctionalInterface public interface Supplier<T> { /** * Get a result and return the T object * @return a result */ T get(); }
Methods in the Supplier interface
T get() Gets the specified type of data
1. Use Supplier directly
Case requirements: the basic use of the get() method. In the Supplier interface, the get method returns a string.
Case steps:
- Create a Supplier object using Lambda. The generic type is String. The method body returns a String. return can be omitted.
- Call the Supplier's get() method to get the string and print it out
public class LambdaTest { public static void main(String[] args) { //Creating a Supplier object using Lambda Supplier supplier = () -> "Hello Java!"; //Output its value System.out.println(supplier.get()); } } // output // Hello Java!
2. Use Supplier to generate objects
Case requirements:
The following example demonstrates how to generate an employee object return by calling a static method. Use the constructor as a reference to the Supplier parameter.
Case steps:
- Create a private static Employee object inside the main class, override the toString() method, and return a string: "I am an Employee".
- Create a Supplier object in the main function, and the generic type is Employee. Use Lambda to pass in the Supplier object, instantiate the Employee object in the method body, and omit the return method.
- Use the get() method of the supplier object to get the employee object
- Print out employee objects
Because the Employee object is private, external classes cannot directly instantiate the Employee object.
Call the Supplier's get() method to generate the employee object. The purpose of this is to control the generation method of the employee object, similar to the factory mode.
public class LambdaTest { public static void main(String[] args) { //If you use Lambda to pass in the Supplier object, an employee object will be generated //At this time, only the interface is instantiated and the code inside is not executed Supplier supplier = ()->new Employee(); //Output employee object System.out.println(supplier.get()); } //Employee category private static class Employee {//Pay attention to static @Override public String toString() { return "I'm an employee"; } } } // output // I'm an employee
3. Take Supplier as the parameter of the method
Requirement Description: find the maximum value in the array, use the Supplier interface as the method parameter type, and find the maximum value in the int array through Lambda expression.
Demand analysis:
- Define integer array int [] arr = {12,68,10,2,99313,46};
- Create static method getMax(): return int type, take Supplier as parameter, the generic type is Integer, and the method body calls get() method to return value.
- In the main function, we call the getMax() method, use Lambda to import the Supplier object, and realize the function of finding the maximum value.
- The Lambda expression is equivalent to the method body: traverse each element, compare the size, and find the maximum value.
public class LambdaTest { public static void main(String[] args) { int[] arr = {12, 68, 10, 2, 99, 313, 46}; // Call the getMax method to get the maximum value. Lambda is equivalent to the method body int num = getMax(() -> { int max = arr[0]; for (int i = 1; i < arr.length; i++) { if (max < arr[i]) { max = arr[i]; } } return max; }); //Maximum output System.out.println("The maximum value is:" + num); } //Use Supplier as parameter public static int getMax(Supplier<Integer> supplier) { return supplier.get(); } } // output // The maximum value is 313
2, Consumer interface
The Consumer interface represents a class of operations that accept a single input variable and have no return value. Its function is opposite to that of a Supplier. It consumes data. The data type of consumption needs to be specified through generics.
The source code is as follows:
@FunctionalInterface public interface Consumer<T> { /** * Accept t object, no return value */ void accept(T t); /** * The default combination method, parameters and return values are of Consumer type * First call your own accept() method, and then call the accept() method of the parameter */ default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }
Methods in the Consumer interface
void accept(T t) Accepts the operation on the given parameter.
Default methods in the Consumer interface:
default Consumer<T> andThen(Consumer<T> after)
If the parameters and return values of a method are all of consumer < T > type, the effect can be achieved:
When consuming a data, first do one operation, and then do another operation. The two operations are executed in turn to realize a combined operation. This method is the default method andThen in the Consumer interface.
1. Use the Consumer object directly
Implementation steps:
- Create a Consumer object using Lambda to print the incoming string data directly.
- Call the accept() method of the Consumer, and pass in a string data in the accept() method.
public class LambdaTest { public static void main(String[] args) { //Create a Consumer object and print the passed in variable t Consumer consumer = t -> System.out.println(t); //Call the method in the Consumer consumer.accept("Hello Lambda"); } } // output // Hello Lambda
2. Consumer as parameter
The parameter of the forEach method traversed in the List and Set sets is Consumer. Please see the following code:
Case requirements:
- Create an array using arrays Aslist ("Monkey King", "pig Bajie", "Baigujing", "Chang'e") is converted into a List object.
- Use the forEach method to print each element, and use the Lamba expression in forEach to output the incoming string
public class LambdaTest { public static void main(String[] args) { //Convert array to List object List<String> names = Arrays.asList("Sun WuKong", "Zhu Bajie", "Baigujing", "Chang'e"); //Print each string, and the parameter of forEach is Consumer names.forEach(t -> System.out.println(t)); } } // output //Sun WuKong //Zhu Bajie //Baigujing //Chang'e
Analyze the source code of the forEach() method
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
This is defined in Java The default method in the lang. Iterable interface. The parameter is the Consumer object. The method body uses for to traverse the current collection, and this is the collection object. The accept() method is called one element at a time. We implement the accept() method in the external calling code and output each element.
public static # T requireNonNull(T obj) static method, a new method in JDK7, determines whether the incoming object is NULL. If it is NULL, an exception is thrown. If it is not NULL, the object itself is returned. It is often used to verify the passed in object parameters in methods or construction methods.
default Consumer<T> andThen(Consumer<? super T> after) { //Determine whether after is null Objects.requireNonNull(after); //First call your own accept() method, and then call the accept() method of the parameter return (T t) -> { accept(t); after.accept(t); }; } To achieve composition, you need two or more Lambda Expression, and andThen The semantics of is to perform "step by step" operations.
Case requirements: print the string hello first in uppercase Hello, and then in lowercase hello
Implementation steps:
- Create the Consumer object c1 and print the uppercase of the s object using Lambda
- Create the Consumer object c2 and print the lowercase of the s object using Lambda
- c1 calls the andThen(c2) method, and then calls accept("string") to complete the sequential operations.
public class LambdaTest { public static void main(String[] args) { //Print uppercase Consumer<String> c1 = s -> System.out.println(s.toUpperCase()); //Print lowercase Consumer<String> c2 = s-> System.out.println(s.toLowerCase()); //Call method c1.andThen(c2).accept("Hello Consumer"); } } // output // HELLO CONSUMER // hello consumer
3. Use Consumer as the parameter
Requirements Description:
Format the print information. There are multiple pieces of information in the following string array. Please follow the format "Name: XX. Gender: XX." Print the information in a format. It is required to take the action of printing name as the Lambda instance of the first Consumer interface and the action of printing gender as the Lambda instance of the second Consumer interface, and "splice" the two Consumer interfaces together in order. The following array consists of 5 elements, each containing 2 items of information, separated by commas.
String[] arr = {"Zhang Fei, male", "Diao Chan, female", "Cao Cao, male", "sun Shangxiang, female", "Xiao Qiao, female"};
Implementation steps
- Create a static method printInfo(), which has three parameters. The first is the string array to be printed, the second is the Consumer to print the name, and the third is the Consumer to print the gender.
- Traverse each element in the array in the printInfo method, and then call name andThen(gender). Accept (single element)
- Each time the andThen() method is called, a horizontal line is output below
- Create the array to be traversed above in the main function
- Call the printInfo method and pass in three parameters. The first parameter is the array, the second parameter uses Lambda to print the name, and the parameter s represents each element in the array. The third parameter uses Lambda to print gender.
public class LambdaTest { public static void main(String[] args) { String[] arr = {"Fei Zhang,male", "army officer's hat ornaments,female", "Cao Cao,male","Sun Shangxiang,female"}; //s here represents each element in the array printInfo(arr, s ->System.out.println("full name:" + s.split(",")[0]), s ->System.out.println("Gender:" + s.split(",")[1])); } public static void printInfo(String[] arr, Consumer<String> name, Consumer<String> gender) { for (String s : arr) { name.andThen(gender).accept(s); System.out.println("------------------"); } } }
3, Predict interface
Predict means Predicate in Chinese, "I'm a programmer", "yes" or "no" is the Predicate.
It represents a function with only one variable and returns boolean type. Sometimes we need to make some judgment to get a Boolean value. You can use Java util. function. Predict interface.
@FunctionalInterface public interface Predicate<T> { /** * Abstract method, test t and return boolean type */ boolean test(T t); /** * Combination method, short circuit the current predicate with another predicate, and return a predicate object */ default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } /** * Perform a logical non operation on the current predicate and return a predicate object */ default Predicate<T> negate() { return (t) -> !test(t); } /** * Combination method, short circuit the current predicate with another predicate, and return a predicate object */ default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } /** * Static method to judge whether the object passed in by the test(object) method is equal to the parameter targetRef object */ static <T> Predicate<T> isEqual(Object targetRef) { return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); } }
Methods in predict interface
boolean test(T t) yes t Test the specified conditions and return boolean type
1. test() method demonstration
Case requirements: judge whether the parameter length given by the test("string") method is greater than 5
Case steps:
- Create a Predicate predicate object and use Lambda to implement the Boolean test (T) method
- The parameter of the method body is s, the length of the returned string is greater than 5, and the return keyword is omitted.
- Call the test() method twice to see the running results. For the first time, use the string Hello and for the second time, use the string predict
public class LambdaTest { public static void main(String[] args) { //Create a Predicate predicate object. The Boolean test (T) method receives the string type and returns the boolean type Predicate<String> predicate = s -> s.length() > 5; //Call the test method twice to see the running result System.out.println("Hello Is the length greater than 5:" + predicate.test("Hello")); System.out.println("Predicate Is the length greater than 5:" + predicate.test("Predicate")); } } // results of enforcement // Is the length of Hello greater than 5: false // Is the length of Predicate greater than 5: true
2. Default method and()
Since it is conditional judgment, there will be three common logical relationships: and, or and non. The default method and can be used when two Predicate conditions are connected with and logic to achieve the effect of "and". This default method receives a Predicate parameter and returns a Predicate parameter.
Its JDK source code is:
/** * Combination method, short circuit the current predicate with another predicate, and return a predicate object */ default Predicate<T> and(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); }
and method demonstration example:
Case requirements: judge whether a string contains the specified string: both uppercase "H" and uppercase "W"
Case steps:
- Create 2 strings to be judged: s1="Hello world" and s2="Hello World"
- Using a Lambda expression, create two Predicate objects
- Judge whether the string s contains H
- Judge whether the string s contains W
- Call the and method and test method to output s1 and s2 results respectively
public class LambdaTest { public static void main(String[] args) { //Create 2 strings to be judged String s1 = "Hello world"; String s2 = "Hello World"; // Using a Lambda expression, create two Predicate objects //Judge whether s contains H Predicate<String> p1 = s -> s.contains("H"); //Judge whether s contains W Predicate<String> p2 = s -> s.contains("W"); //Call the and method System.out.println(s1 + "Include H and W: " + p1.and(p2).test(s1)); System.out.println(s2 + "Include H and W: " + p1.and(p2).test(s2)); } } // Output results // Does Hello world contain H and W: false // Does Hello World contain H and W: true
3. Default method (or)
Similar to the and of and, the default method or implements the or operation in the logical relationship. This default method receives a Predicate parameter and returns a Predicate parameter.
The JDK source code is:
/** * Combination method, short circuit the current predicate with another predicate, and return a predicate object */ default Predicate<T> or(Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); }
or method demonstration example:
Case requirements: judge whether the length of a string is greater than 10 or less than 5
Case steps:
- Create three strings S1, S2 and S3, as shown in the following figure
- Use Lambda to create two Predicate interface objects. The first determines whether the length is greater than 10 and every two determines whether the length is less than 5
- Call the or and test methods to output the test results of each string
public class LambdaTest { public static void main(String[] args) { //Create three strings String s1 = "Hello World"; //Greater than 10 String s2 = "Java"; //Less than 5 String s3 = "I am boy"; //Not more than 10 and not less than 5 //Create 2 Predicate interface objects using Lambda Predicate<String> p1 = s -> s.length() > 10; Predicate<String> p2 = s -> s.length() < 5; //Output test results for each string System.out.println(s1 + "=" + p1.or(p2).test(s1)); System.out.println(s2 + "=" + p1.or(p2).test(s2)); System.out.println(s3 + "=" + p1.or(p2).test(s3)); } } // Output results // Hello World=true // Java=true // I am boy=false
4. Default method negate()
"And" and "or" have been understood, and the remaining "not" (negative) will also be simple. The method has no parameters and the return value is predict.
The JDK source code of the default method negate is:
/** * Perform a logical non operation on the current predicate and return a predicate object */ default Predicate<T> negate() { return (t) -> !test(t); } It is easy to see from the implementation that it is executed test After the method, the results boolean Value proceed“!"Take it instead. To be in test Call before method invocation negate Method, as and and or The method is the same.
Case requirements: judge whether the age is less than 18 years old and take the judgment result inversely.
Case steps
- Create 2 integer types of ages, one 25 and one 15.
- Create a Predicate using Lambda to judge that the age is less than 18 years old.
- Use the negate () method and then call the test() method to output the results of two ages
public class LambdaTest { public static void main(String[] args) { int age1 = 25; //25 years old int age2 = 15; //15 years old Predicate<Integer> predicate = (a) -> a < 18; //Judge whether he is less than 18 years old System.out.println(age1 + "Less than 18 years old, reverse:" + predicate.negate().test(age1)); System.out.println(age2 + "Less than 18 years old, reverse:" + predicate.negate().test(age2)); } } // results of enforcement // If 25 is less than 18 years old, take the inverse: true // 15 less than 18 years old, negative: false
5. Static method isEqual()
The only static method in Predicate. The parameters of the method are two Object types and return a Predicate type.
Function: according to objects The equals (object, object) method compares whether the two parameters are equal,
One object is passed in through isEqual() and the other object is passed in through test().
// java. util. Method description in objects class public static boolean equals(Object a,Object b)
Function: used to compare whether two objects are equal
Parameters: a and b are the two objects to compare
Return: if two objects are equal, return true; otherwise, return false
The JDK source code is:
/** * Static method to judge whether the object passed in by the test(object) method is equal to the parameter targetRef object */ static <T> Predicate<T> isEqual(Object targetRef) { return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); }
Case requirements: compare whether two strings are equal
Case steps:
- Directly return the Predicate object through the static method isEqual("newboy")
- Call the test() method in predict to pass in another two strings for comparison
public class LambdaTest { public static void main(String[] args) { //The predict object is returned directly through a static method Predicate predicate = Predicate.isEqual("newboy"); //Call the test() method to pass in another two strings for comparison System.out.println("Whether the two strings are equal:" + predicate.test("newboy")); System.out.println("Whether the two strings are equal:" + predicate.test("NewBoy")); } } // results of enforcement // Whether two strings are equal: true // Whether the two strings are equal: false
6. Application example of predict
Requirements Description:
There are multiple "name + gender" information in the set as follows: "Zhang Fei, male", "Diao Chan, female", "Cao Cao, male", "sun Shangxiang, female", "Xiao Qiao, female". Please filter the qualified strings into the set ArrayList through the and combination method of the Predicate interface. Two conditions need to be met at the same time:
- Must be a girl
- The name is two words
Development steps:
- Create the first Predicate judgment condition: the length of the 0-th element name separated by commas is 2
- Create the second Predicate judgment condition: the first element separated by commas has gender equal to female
- Create a new List collection to store qualified strings after filtering
- Use forEach(Lambda) in the List to traverse the original List set above, and use the and and test methods in predict to judge each element
- Both conditions are true and added to the new List collection
- Create the first Consumer interface and output the names of the 0th element separated by commas
- Create the second Consumer interface and output the first element separated by commas
- Use forEach(Lambda) in the List to traverse and output the filtered new collection
- Use the andThen and accept methods in the Consumer interface to output each element
public class LambdaTest { public static void main(String[] args) { //Create a List collection from the array List<String> list = Arrays.asList("Fei Zhang,male", "army officer's hat ornaments,female", "Cao Cao,male","Sun Shangxiang,female","Little Joe,female"); //Create the first Predicate judgment condition: the length of the 0-th element name separated by commas is 2 Predicate<String> pname = s -> s.split(",")[0].length() ==2; //Create the second Predicate judgment condition: the first element separated by commas has gender equal to female Predicate<String> pgender = s-> s.split(",")[1].equals("female"); //Create a new List collection List<String> infos = new ArrayList<>(); //Use forEach() in Lamba to traverse the List collection above //Use the and and test methods in predict to determine each element list.forEach(s -> { //Both are genuine talents added to the collection if (pname.and(pgender).test(s)) { infos.add(s); } }); //Create the first Consumer interface and output the names of the 0th element separated by commas Consumer<String> cname = s -> System.out.println("full name:" + s.split(",")[0]); //Create the second Consumer interface and output the first element separated by commas Consumer<String> cgender = s -> System.out.println("Gender:" + s.split(",")[1]); //Use forEach() in Lamba to traverse and output the filtered collection infos.forEach(s -> { //Use the andThen and accept methods in the Consumer interface, one line apart for each output element cname.andThen(cgender).accept(s); System.out.println("---------------"); }); } } // Output results Name: Diao Chan Gender: Female --------------- Name: Xiao Qiao Gender: Female ---------------
4, Function interface
Function interface:
Get another parameter value according to one parameter, which is called the calculated parameter in the front and the calculated result in the back.
There are in and out, so it is called "Function".
Similar to a function in mathematics, the value of one variable is obtained from another. For example: f(x) = 2x+3
The following is its Java source code:
// A function that represents the result of one variable from another @FunctionalInterface public interface Function<T, R> { /** * Calculate the given variable t to get the returned result R */ R apply(T t); /** * The default combination method is to calculate the current function first and then the incoming function */ default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } /** * The default combination method is to calculate the incoming function first, and then the current function */ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } /** * Static method: always returns its input variable */ static <T> Function<T, T> identity() { return t -> t; } }
1. Abstract method: apply()
It's Java util. function. Methods in function interface
R apply(T t); Calculate the given variable t to get the returned result R
Demo example of apply method:
Case requirements: convert Integer type to String type, and output the length of the converted String.
- Create a Function object. The input type is integer and the output type is string
- Lambda expressions convert an integer i into a string
- Call the apply (number) method to get the converted String, and then call the length() method of the string to get the length and print out
- The number 99 is converted for the first time, and the number 1000 is converted for the second time
public class LambdaTest { public static void main(String[] args) { //Create a Function object Function<Integer,String> converter = i -> Integer.toString(i); System.out.println("99 The length of conversion to string is:" + converter.apply(99).length()); System.out.println("1000 The length of conversion to string is:" + converter.apply(1000).length()); } } // Output results 99 The length of conversion to string is: 2 1000 The length of conversion to string is: 4
2. Default method: andThen()
There is a default andThen method in the Function interface, which is used for combination operations.
First calculate the current function, and then calculate the incoming function. The two functions are executed in turn.
The parameter of andThen method is a Function object, which returns a Function object.
JDK source code:
/** * The default combination method is to calculate the current function first and then the incoming function */ default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); }
Case requirements:
There are two consecutive operations: the first operation is to convert the string into an int number, and the second operation multiplies the converted number by 10. The two operations are combined in sequence.
- Let the user input a number from the keyboard and receive it with a string.
- Create the first Function function to convert the string to an integer
- Create the second function and multiply the integer by 10 to return
- Call the andThen method and apply, and output the result
public class LambdaTest { public static void main(String[] args) { //The user enters a string System.out.println("Please enter a number:"); Scanner input = new Scanner(System.in); String str = input.nextLine(); //The first function converts a string to an integer Function<String,Integer> f1 = s -> Integer.parseInt(s); //The second function multiplies the integer by 10 to return Function<Integer,Integer> f2 = i -> i * 10; //Call the andThen method and output the result System.out.println("Converted to an integer and multiplied by 10, the result is:" + f1.andThen(f2).apply(str)); } } // Output results Please enter a number: 2 After converting to an integer and multiplying by 10, the result is: 20
3. Default method: compose()
Function has a compose method very similar to andThen.
Chinese means "composition". The method parameter is Function and the return value is Function. Run the apply method of the parameter first, and then call your own apply method.
Its JDK source code is:
/** * The default combination method is to calculate the incoming function first, and then the current function */ default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } // Compared with the JDK source code implementation of andThen method, it can be found that the parameter Lamda of compose method will be executed first. So the two are just different in order.
Demo of compose method
Case requirements:
Create two function objects: one to convert the string to uppercase and one to lowercase. Use the andThen and compose methods to combine calls to view different calculation results.
Development steps:
- Create the first Function. The input and output are of String type. Convert the String to uppercase.
- Create the second Function. The input and output are of String type. Convert the String to lowercase.
- Call the apply method of the first function and output the value
- Call the apply method of the second function and output the value
- Call the andThen method and the apply method to view the running results
- Call the compose method and the apply method to view the running results
public class LambdaTest { public static void main(String[] args) { Function<String, String> f1 = s -> s.toUpperCase(); Function<String, String> f2 = s -> s.toLowerCase(); System.out.println("Convert to capital:" + f1.apply("Hello")); System.out.println("Convert to lowercase:" + f2.apply("Hello")); System.out.println("Convert to uppercase and then lowercase:" + f1.andThen(f2).apply("Hello")); System.out.println("Convert to lowercase and then uppercase:" + f1.compose(f2).apply("Hello")); } } // results of enforcement Convert to capital: HELLO Convert to lowercase: hello Convert to uppercase and then lowercase: hello Convert to lowercase and then uppercase: HELLO
Application example of Function
Requirement Description: please use Function to splice functions and execute multiple functions in order.
The operations are as follows:
- Intercept the digital age part of the string "Zhao Liying, 20" to obtain the string;
- Convert the string in the previous step into a number of type int;
- Accumulate the int number of the previous step by 100 to obtain the result int number.
Development steps:
- Create the first Function object, take out the string 20 and return a string
- Create the second Function object, convert the string to an integer, and return an integer
- Create the third Function object, add the integer by 100, and return the calculation result. 4) call the andThen method twice, apply the string: "Zhao Liying, 20", and output the result
code implementation
public class LambdaTest { public static void main(String[] args) { //Create the first Function object, take out the string 20 and return a string Function<String,String> fun1 = s -> s.split(",")[1]; //Create the second Function object, convert the string to an integer, and return an integer Function<String,Integer> fun2 = s -> Integer.parseInt(s); //Create the third Function object, add the integer by 100, and return the calculation result Function<Integer,Integer> fun3 = num -> num + 100; //Call the andThen method twice, apply the string and output the result System.out.println("Calculation results:" + fun1.andThen(fun2).andThen(fun3).apply("Zhao Liying,20")); } } //Output results Calculation result: 120
5, BinaryOperator interface
BinaryOperator means to operate on two operands of the same type to produce the same type of results.
Methods in interfaces
static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) Return a BinaryOperator ,It is based on the specified Comparator Returns the larger of two elements Comparator . static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) return BinaryOperator Returns the smaller of the two components specified Comparator . Two static methods are defined in this interface, BiFunction Is a function interface for defining two operators.
Methods in BiFunction interface
T apply(T t, T u); From parent interface BiFunction Abstract methods inherited from, Pass in two parameters t and u Perform function calculation and return the calculation result. Both parameters and return values are of the same type. default <V> BiFunction<T,U,V> andThen(Function<? super R,? extends V> after) Returns a composite function that is first applied to its input, and then after Function is applied to the result. If the evaluation of any function throws an exception, it is forwarded to the caller of the composite function.
1. Method demonstration: apply()
Case requirements:
Use the apply() method of the BinaryOperator interface to calculate the sum of two integers and output the result.
Case steps:
- Create class Demo25BinaryOperator
- Create a BinaryOperator interface and use Lambda to implement the method. The method has two parameters and returns the calculation result of the method.
- Call the apply() method to pass in the actual parameters and print the calculation results.
Case code:
public class LambdaTest { public static void main(String[] args) { BinaryOperator<Integer> operator = (m, n) -> m + n; System.out.println("The calculation result is:" + operator.apply(3, 5)); } } // Output results The calculation result is: 8
Static method
ublic static BinaryOperator minBy(Comparator comparator) Through the back Comparator The comparator judges and returns the smaller of the two elements public static BinaryOperator maxBy(Comparator comparator) Through the back Comparator The comparator judges and returns the larger of the two elements Comparator Static method description in interface naturalOrder() Compare by the size of the natural sorting of elements, and return a Comparator object reverseOrder() Compares the size of elements in reverse order and returns a Comparator object
2. BinaryOperator interface as method parameter
Case requirements:
There is the following array {2,1,3,5} to replace each element in the array. The replacement algorithm is as follows:
- The 0th element remains unchanged
- The result of element 0 + element 1 replaces element 1
- The result of the first new element + the second element replaces the two
- The result of the second new element + the third element replaces the third
- And so on until all elements are replaced.
//Method description in the Arrays class void parallelPrefix(T[] array, BinaryOperator op) Function: use the specified binary operation function to replace each element in the array and accumulate in parallel Parameter 1: array to replace Parameter 2: specify binary operation function
Case steps
- Create BinaryOperator object, and the algorithm of specifying 2 numbers is m+n
- Create an array of Integer type: {2,1,3,5}
- Array before output operation
- Call the parallelPrefix() method above and pass in BinaryOperator as a parameter
- Array after output operation
- If different algorithms are used, the replacement result of each element is different. For example, multiply two numbers.
Case code
public class LambdaTest { public static void main(String[] args) { BinaryOperator<Integer> operator = (m,n) -> m+n; Integer [] arr = {2,1,3,5}; System.out.println("Array before operation:" + Arrays.toString(arr)) ; Arrays.parallelPrefix(arr,operator); System.out.println("Array after operation:" + Arrays.toString(arr)) ; } } //Output results Array before operation:[2, 1, 3, 5] Array after operation:[2, 3, 6, 11]
3. Demonstration of static methods
Case requirements:
Compare two integers, use the minBy static method to find the minimum value, compare two strings, and use the maxBy static method to find the maximum value
Case steps
- Create a BinaryOperator object and use the minBy() static method to compare the normal size of the number.
- Output the minimum value, call the apply() method, and pass in 2 integers.
- Create a BinaryOperator object and use the maxBy() static method to compare the size of the string.
- Output the maximum value, call the apply() method, and pass in two strings: "ABCD","xyz"
Case code
public class LambdaTest { public static void main(String[] args) { //naturalOrder() is a static method in Comparator that compares numbers by their normal size BinaryOperator oper1 = BinaryOperator.minBy(Comparator.naturalOrder()); System.out.println("The minimum value is:" + oper1.apply(3,5)); //naturalOrder() is a static method in Comparator that compares strings according to their normal size BinaryOperator oper2 = BinaryOperator.maxBy(Comparator.naturalOrder()); System.out.println("The maximum value is:" + oper2.apply("ABCD","xyz")); } } // Output results The minimum value is: 3 The maximum value is: xyz
6, UnaryOperator interface
UnaryOperator represents an operation on a single operand that produces the same result as its operand type.
The UnaryOperator interface inherits from the Function interface,
Therefore, there is a t apply (t t t) abstract method, which is the same as the apply() method in the previous Function interface.
Its input type and return type are the same type.
Source code of UnaryOperator interface
@FunctionalInterface public interface UnaryOperator<T> extends Function<T, T> { /** * A unary operator that always returns its input parameters */ static <T> UnaryOperator<T> identity() { return t -> t; } }
Method demonstration
UnaryOperator Method description in interface T apply(T t); from Function The abstract method inherited from the interface applies this unary operation function with the given parameters and returns another value. Parameter and return value are of the same type. static UnaryOperator identity() The unary operator that always returns its input parameters, that is, the subsequent operator apply()Return whatever you enter.
Case steps
- Use UnaryOperator The identity () static method creates an UnaryOperator object
- Using the apply() method, enter the string abc, and the result is also abc.
public class LambdaTest { public static void main(String[] args) { //Create an UnaryOperator object, UnaryOperator operator = UnaryOperator.identity(); //Call the apply() method to output the value of the parameter System.out.println("The output is the same as the input:" + operator.apply("abc")); } } //Output results The output is the same as the input: abc
Parameters of the method used by UnaryOperator
Case requirements:
There is a list set of integers. Multiply each element in the set by 2, and then replace this element. The list set before and after replacement is output. There is a list set of strings, and each element in the set is replaced with its uppercase.
ArrayList Method description in replaceAll(UnaryOperator operator) Replace each element in the list with the result of a unary operation function
Case steps:
- Use arrays Aslist() creates a list of integers
- Create UnaryOperator unary operation function and specify that the operation expression is x*2
- Call the replaceAll() method of ArrayList and pass the unary operation function created above as a parameter
- Output list before and after replacement
- Use arrays Aslist() creates a list of strings
- This time, the Lambda expression is directly passed in the replaceAll() method, s.toUpperCase()
- Output list before and after replacement
public class LambdaTest { public static void main(String[] args) { List<Integer> nums = Arrays.asList(3, 10, 8, 2); System.out.println("Before replacement:" + nums); UnaryOperator<Integer> oper = x -> x * 2; nums.replaceAll(oper); System.out.println("After replacement:" + nums); List<String> names = Arrays.asList("Jack","Rose","Tom","NewBoy"); System.out.println("Before replacement:" + names); names.replaceAll(s -> s.toUpperCase()); System.out.println("After replacement:" + names); } } //output Before replacement:[3, 10, 8, 2] After replacement:[6, 20, 16, 4] Before replacement:[Jack, Rose, Tom, NewBoy] After replacement:[JACK, ROSE, TOM, NEWBOY]
7, Summary of common functional interfaces
(1) Supplier data provider
- T get(); There are no parameters passed in and there are results.
(2) Consumer consumer data
- void accept(T t); Incoming data, no results.
- andThen()
(3) Predicate predicate
- boolean test(T t); Logical judgment of incoming data
- and()
- or()
- negate()
- isEqual()
(4) Function function
- R apply(T t); Pass in a variable to return the calculation result
- andThen()
- compose()
- identity()
(5) BinaryOperator binary operator
- T apply(T t,T u); Pass in two parameters and return a result
- andThen()
- Inherited from BiFunction
(6)UnaryOperator
- Inherited from Function
- Unary operator
- T apply(T t); Pass in a parameter and return a result
- andThen()
- compose()
- identity()
reference resources:
Java 8 functional interface
https://www.runoob.com/java/java8-functional-interfaces.html
Dead knock functional interface - common functional interface
Common functional interfaces