catalogue
2. Functional interface features:
3. Functional interface summary:
2. Syntax of lambda expression:
4. There are three ways to write lambda expressions:
Expression single statement expression:
5. Summary of main features of lambda expression:
3, Implementation cases of common lambda expressions
1. Implement Runnable with lambda expression
2. Use Java 8 lambda expression for event processing
3. Iterate over the list using lambda expressions
4. Use lambda expression and functional interface predict
5. How to add Predicate in lambda expression
6. Map and Reduce examples using lambda expressions in Java 8
7. Create a String list by filtering
8. Apply a function to each element of the list
9. Copy different values and create a sub list
10. Calculate the maximum, minimum, sum and average values of set elements
1, Functional interface
A functional interface with only one abstract method, except the public method of Object.
1. Syntax:
@FunctionalInterface public interface Func{ Object clone(); // Object method void run(); // Custom abstract method }
2. Functional interface features:
- The @ FunctionalInterface annotation is marked in the interface
- Only one abstract method in the interface is automatically recognized as a functional interface by the compiler
- There is an abstract method in the interface, and other abstract methods that contain the Object class will also be recognized as abstract interfaces
3. Functional interface summary:
name | Unary interface | explain | Binary interface | explain |
General function | Function | Unary function, abstract apply method | BiFunction | Binary function, abstract apply method |
Operator function (input and output of the same type) | UnaryOperator | Unary operator, abstract apply method | BinaryOperator | Binary operator, abstract, apply method |
Predicate function (output boolean) | Predicate | Unary predicate, abstract test method | BiPredicate | Binary predicate, abstract test method |
Consumer (no return value) | Consumer | Unary consumer function, abstract accept method | BiConsumer | Binary consumer, abstract accept method |
Supplier (no parameters, only return value) | Supplier | Provider function, abstract get method | - | - |
2, lambda
1.lambda preconditions:
- You must have a functional interface to use lambda expressions
2. Syntax of lambda expression:
(Parameter name) -> {Code block}; // Single line can not add {}, and multiple lines must add {} LambdaParameters -> LambdaBody args -> expr perhaps(object... args) -> {Functional interface abstract method implementation logic} 1.()The number of parameters is determined according to the number of abstract parameters in the functional interface. When there is only one parameter,()Can be omitted 2.When expr When the logic is very simple,{}and return Can be omitted
3. Expression cases
()->{} ()->{System.out.println(1);} ()->System.out.println(1) ()->{return 100;} ()->100 ()->null (int x)->{return x+1;} (int x)->x+1 (x)->x+1 x->x+1
4. There are three ways to write lambda expressions:
1) expression: single statement expression
2) statement: statement block
3) reference: method reference
Expression single statement expression:
There is no need to write the return keyword in the expression expression. The interpreter will automatically return the evaluation result of the expression.
// Example: (parameter) - > expression static <T> Function<T, T> identity() { return t -> t; // here }
statement block:
The statement statement block wraps multiple statements through braces {}. If it is an interface that needs to return results, it must be displayed, and return must be added to indicate the returned variables
// Example: (parameter) - > {} // No return value: public interface MyInterface{ void test(String n, String c); } public static void testLambada1(){ MyInterface myInterface = (String n,String c) -> { System.out.println(n); System.out.println(c); }; myInterface.test("abc","123"); } // With return value: public interface MyInterface1{ String test1(String n, String c); } public static void testLambada2(){ MyInterface1 myInterface = (String n,String c) -> { System.out.println(n); System.out.println(c); return n + c; }; System.out.println(myInterface.test1("abc","123")); }
Reference method reference:
If a method is structurally matched with the corresponding method in the lambada expression, it can be directly referenced to the lambada expression, which contains a total of four reference types. The syntax format is shown in the table:
type | grammar |
---|---|
Instance based method reference | object::methodName |
Construction method reference | className::new |
Parameter instance based method reference | className::methodName |
Static method reference | className::staticMethodName |
Instance based method reference (example):
package com.test.demo; import java.util.function.Supplier; import java.util.function.UnaryOperator; /** * Created by xiaobaiaixuexi on 2022-1-10 */ public class InstantMethodUse { String put() { return "hello"; } public String toUpCase(String s) { return s.toUpperCase(); } // Call the method of the current instance void test() { UnaryOperator<String> unaryOperator = this::toUpCase; System.out.println(unaryOperator.apply("this inst method")); } public static void main(String[] args) { Supplier<String> stringSupplier = () -> new InstantMethodUse().put(); Supplier<String> stringSupplier1 = () -> { return new InstantMethodUse().put(); }; Supplier<String> stringSupplier2 = new InstantMethodUse()::put; System.out.println(stringSupplier2.get()); //Common lambda expressions use Supplier<String> stringSupplier3 = () -> new InstantMethodUse().put(); //Two ways to use UnaryOperator<String> unaryOperator = new InstantMethodUse()::toUpCase; //New object reference InstantMethodUse instantMethodUse = new InstantMethodUse(); UnaryOperator<String> unaryOperator1 = instantMethodUse::toUpCase; System.out.println(unaryOperator.apply("lambda instMethod Use") + " === " + unaryOperator1.apply("lambda instMethod Use")); instantMethodUse.test(); } }
Construction method reference (example):
// Construction method reference example: public interface MyInterface{ // Get all List<String> getAll(); } public static void main(String[] args){ MyInterface i = ArrayList:new; }
Parameter based method reference (example):
// Parameter based method reference (example): public interface MyInterface{ // Compare it void compare(String str1, String str2); } pulbic static void main(String[] args){ MyInterface i = String::compareTo; }
Based on static method reference (example):
package com.test.demo; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; /** * Created by xiaobaiaixuexi on 2022-1-10 */ public class StaticMethodUse { static <T> String hello(T s) { return s.toString(); } static <T> String ret() { return "hello"; } static void getSize(String s) { System.out.println(s.length()); } static String toUpCase(String s){ return s.toUpperCase(); } public static void main(String[] args) { Supplier<String> supplier = () -> hello("hello"); //Use the method to reference Supplier T get(); // 1. Only output parameters are supported, not input parameters, so the following method reports an error //2. Why don't you need parentheses for a reference to a method? Because it is only a reference to a method, it is not executed // Supplier<String> stringSupplier = StaticMethodUse::hello("wqer"); // report errors Supplier<String> s = StaticMethodUse::ret; Supplier<String> supplier1 = Fun::put; Function<Integer, String> function = StaticMethodUse::hello; //The parameters of the method must be passed in when calling, and the functional interface must be called System.out.println("function" + function.apply(123)); //Use of ordinary lambda Consumer<String> consumer = size -> StaticMethodUse.getSize(size); //Why don't you need parentheses for a reference to a method? Because it is only a reference to a method, it is not executed Consumer<String> c1 = StaticMethodUse::getSize; c1.accept("hello use lambda"); //Output parameter uppercase Function<String ,String> function1 = (ss) -> ss.toUpperCase(); Function<String,String> function2 = StaticMethodUse::toUpCase; Function<String,String> function3 = Fun::toUpCase; System.out.println(function1.apply("aasdf")); System.out.println(function2.apply("aasdf")); System.out.println(function3.apply("aasdf")); } } class Fun { static String put() { return "hello"; } static String toUpCase(String s){ return s.toUpperCase(); } }
5. Summary of main features of lambda expression:
- 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 topic contains a statement, curly braces are not required.
- Optional return keyword: if the body has only one expression return value, the compiler will automatically return the value. Braces need to specify that the expression returns a value.
3, Implementation cases of common lambda expressions
1. Implement Runnable with lambda expression
// Before Java 8: new Thread(new Runnable() { @Override public void run() { System.out.println("Before Java8, too much code for too little to do"); } }).start(); //Java 8 mode: new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
Output:
too much code, for too little to do Lambda expression rocks !!
2. Use Java 8 lambda expression for event processing
If you have used Swing API programming, you will remember how to write event listening code. This is another classic use case of simple anonymous classes in the old version, but it can not be so now. You can write better event listening code with lambda expression, as follows:
// Before Java 8: JButton show = new JButton("Show"); show.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Event handling without lambda expression is boring"); } }); // Java 8 mode: show.addActionListener((e) -> { System.out.println("Light, Camera, Action !! Lambda expressions Rocks"); });
3. Iterate over the list using lambda expressions
// Before Java 8: List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); for (String feature : features) { System.out.println(feature); } // After Java 8: List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API"); features.forEach(n -> System.out.println(n)); // It is more convenient to use the method reference of Java 8. The method reference is marked by:: Double colon operator, // Looks like the scope resolution operator in C + + features.forEach(System.out::println);
Output:
Lambdas Default Method Stream API Date and Time API
4. Use lambda expression and functional interface predict
// In the following code, if an error is reported, you need to add the generic type public static void main(args[]){ List languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp"); System.out.println("Languages which starts with J :"); filter(languages, (str)->str.startsWith("J")); System.out.println("Languages which ends with a "); filter(languages, (str)->str.endsWith("a")); System.out.println("Print all languages :"); filter(languages, (str)->true); System.out.println("Print no language : "); filter(languages, (str)->false); System.out.println("Print language whose length greater than 4:"); filter(languages, (str)->str.length() > 4); } public static void filter(List names, Predicate condition) { for(String name: names) { if(condition.test(name)) { System.out.println(name + " "); } } }
Output:
Languages which starts with J : Java Languages which ends with a Java Scala Print all languages : Java Scala C++ Haskell Lisp Print no language : Print language whose length greater than 4: Scala Haskell
// Better way public static void filter(List names, Predicate condition) { names.stream().filter((name) -> (condition.test(name))).forEach((name) -> { System.out.println(name + " "); }); }
5. How to add Predicate in lambda expression
java.util.function.Predicate allows two OR more predicates to be combined into one. It provides methods similar to the logical operators AND and AND OR, called and(), or(), AND xor(), to combine the conditions passed into the filter() method. For example, to get all four letter languages starting with J, you can define two independent predicate examples to represent each condition, AND then use predicate The and() method combines them as follows:
// You can even combine Predicate with and(), or() and xor() logical functions, // For example, to find all four letter names starting with J, you can merge two predictions and pass them in Predicate<String> startsWithJ = (n) -> n.startsWith("J"); Predicate<String> fourLetterLong = (n) -> n.length() == 4; names.stream() .filter(startsWithJ.and(fourLetterLong)) .forEach((n) -> System.out.print("nName, which starts with 'J' and four letter long is : " + n));
6. Map and Reduce examples using lambda expressions in Java 8
6.1 example 1
// Do not use lambda expressions to add 12% tax to each order List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); for (Integer cost : costBeforeTax) { double price = cost + .12*cost; System.out.println(price); } // Using lambda expressions List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); costBeforeTax.stream().map((cost) -> cost + .12*cost).forEach(System.out::println);
Output:
112.0 224.0 336.0 448.0 560.0 112.0 224.0 336.0 448.0 560.0
6.2 example 2
In the previous example, you can see that the map transforms collection class (such as list) elements. There is also a reduce() function that combines all values into one. Map and reduce operations are the core operations of functional programming. Because of their functions, reduce is also called folding operation. In addition, reduce is not a new operation. You may already be using it. Aggregate functions like sum(), avg(), or count() in SQL are actually reduce operations because they receive multiple values and return a value. The reduceh() function defined by the stream API can accept lambda expressions and merge all values. Classes such as IntStream have built-in methods such as average(), count(), sum() to perform the reduce operation, and mapToLong(), mapToDouble() to perform the conversion. This does not limit you. You can use the built-in method or define it yourself. In the Map Reduce example of Java 8, we first apply a 12% VAT to all prices, and then use the reduce() method to calculate the sum.
// Add 12% tax to each order // Old method: List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); double total = 0; for (Integer cost : costBeforeTax) { double price = cost + .12*cost; total = total + price; } System.out.println("Total : " + total); // new method: List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500); double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum + cost).get(); System.out.println("Total : " + bill);
Output:
Total : 1680.0 Total : 1680.0
7. Create a String list by filtering
Filtering is a common operation of Java developers on large-scale collections, and now filtering large-scale data collections using lambda expressions and stream API s is surprisingly simple. The stream provides a filter() method that accepts a Predicate object, that is, you can pass in a lambda expression as the filtering logic. The following example is to filter Java collections with lambda expressions, which will help you understand.
// Create a list of strings, each with a length greater than 2 List<String> filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList()); System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered);
Output:
Original List : [abc, , bcd, , defg, jk], filtered list : [abc, bcd, defg]
8. Apply a function to each element of the list
We usually need to use a function for each element of the list, such as multiplying by a number one by one, dividing by a number, or doing other operations. These operations are very suitable for the map() method. You can put the conversion logic in the map() method in the form of lambda expression, and then you can convert each element of the set, as shown below.
// Convert strings to uppercase and link them with commas List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "U.K.","Canada"); String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", ")); System.out.println(G7Countries);
Output:
USA, JAPAN, FRANCE, GERMANY, ITALY, U.K., CANADA
9. Copy different values and create a sub list
This example shows how to use the distinct() method of the stream to de duplicate the collection.
// Create a square list with all the different numbers List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4); List<Integer> distinct = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList()); System.out.printf("Original List : %s, Square Without duplicates : %s %n", numbers, distinct);
Output:
Original List : [9, 10, 3, 4, 7, 3, 4], Square Without duplicates : [81, 100, 9, 16, 49]
10. Calculate the maximum, minimum, sum and average values of set elements
There is a very useful method called summaryStatistics() in the classes of streams such as IntStream, LongStream and DoubleStream. You can return IntSummaryStatistics, LongSummaryStatistics, or doublesummarystatistics s to describe various summary data of elements in the stream. In this example, we use this method to calculate the maximum and minimum values of the list. It also has getSum() and getAverage() methods to get the sum and average of all elements of the list.
//Get the number, minimum, maximum, sum and average of numbers List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29); IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("Highest prime number in List : " + stats.getMax()); System.out.println("Lowest prime number in List : " + stats.getMin()); System.out.println("Sum of all prime numbers : " + stats.getSum()); System.out.println("Average of all prime numbers : " + stats.getAverage());
Output:
Highest prime number in List : 29 Lowest prime number in List : 2 Sum of all prime numbers : 129 Average of all prime numbers : 12.9
Author: Xiao Bai loves learning!!
Welcome to follow and forward comments and praise communication. Your support is the driving force of Xiaobai!