Example 1, using lambda expression to implement runnable
When I started using Java 8 o'clock, the first thing I did was to replace the anonymous class with a lambda expression, and the implementation of the Runnable interface was the best example of an anonymous class. Take a look at the runnable implementation before Java 8, which requires 4 lines of code, whereas using a lambda expression requires only one line of code. What have we done here? That is to replace the entire anonymous class with the () {} code block.
// before Java 8: New Thread (new Runnable () {@Overridepublicvoid run () {System.out.println ( "Before Java8, too much code for too little");}). Start (); // Java 8 Way: New Thread (()-System.out.println ("in Java8, Lambda expression Rocks!"). Start ();
Output:
Too much code, for too little
LAMBDA expression Rocks!!
This example shows us the syntax of the Java 8 lambda expression. You can use lambda to write the following code:
(params), expression
(params)-statement
(params), {statements}
For example, if your method does not modify and rewrite the parameters, just print something in the console, then you can write:
() System.out.println ("Hello Lambda Expressions");
If your method receives two parameters, it can be written as follows:
(intint odd), even + odd
Incidentally, the name of the internal variable of the lambda expression is usually shortened. This allows the code to be shortened and put on the same line. Therefore, in the above code, the variable name to choose a, b or X, Y will be better than even, odd.
Example 2, using a Java 8 lambda expression for event handling
If you have used the Swing API programming, you will remember how to write the event listener code. This is another classic use case for an old version of a simple anonymous class, but now it's not possible. You can use lambda expressions to write better event-listening code, as follows:
// before Java 8: JButton show = new JButton ("Show" new ActionListener () {@Override public Span style= "color: #0000ff;" >void actionperformed (ActionEvent e) {System.out.println (" Event Handling without lambda expression is boring " // Java 8 way: Show.addactionlistener ((e)-> light, Camera, Action!!) Lambda Expressions Rocks "
Another place where Java developers often use anonymous classes is to customize the Comparator for Collections.sort (). In Java 8, you can replace an ugly anonymous class with a more readable lambda expression. It should not be difficult for me to leave this for practice, as I do in the process of implementing Runnable and ActionListener using lambda expressions.
Example 3, iterating the list using a lambda expression
If you have been in Java for a few years, you know that the most common operation for a collection class is to iterate and apply the business logic to individual elements, such as a list of orders, transactions, and events. Since Java is an imperative language, all of the loop code before Java 8 is sequential, meaning that its elements can be parallelized. If you want to do parallel filtering, you need to write your own code, which is not so easy. By introducing lambda expressions and default methods, the question of what to do and how to do it is separated, which means that the Java collection now knows how to iterate, and the collection elements can be processed in parallel at the API level. In the following example, I'll show you how to iterate through a list using lambda or not using a lambda expression. You can see that the list now has a ForEach () method that iterates over all the objects and applies your lambda code to it.
// 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", System.out. println (n)); // a method reference using Java 8 is more convenient, and the method reference is indicated by:: Double-colon operator, // looks like the scope resolution operator for C + + Features.foreach (system.out::p rintln);
Output:
Lambdas
Default Method
Stream API
Date and Time API
The last example of a list loop shows how to use method reference in Java 8. You can see that the double colon, scope resolution operators in C + + are now used in Java 8 to represent method references.
Example 4, using lambda expressions and functional interfaces predicate
In addition to supporting functional programming styles at the language level, Java 8 also adds a package called java.util.function. It contains a number of classes to support functional programming in Java. One of these is predicate, which uses the Java.util.function.Predicate function interface and lambda expressions to add logic to the API methods and to support more dynamic behavior with less code. The following is an example of Java 8 predicate, which shows a number of common ways to filter collection data. The predicate interface is ideal for filtering.
Public Static voidMain (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 voidFilter (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 (condition.test (name))). ForEach ((name),+ "");});
As you can see, the Stream API's filtering method also accepts a predicate, which means that we can replace our custom filter () method with the inline code written inside, which is the magic of the lambda expression. In addition, the predicate interface allows multiple conditions to be tested, as the next example will cover.
Example 5, how to add a predicate to a lambda expression
As the last example says, Java.util.function.Predicate allows two or more predicate to be synthesized. It provides a method similar to the logical operators and and OR, called and (), or (), and XOR (), to combine the conditions of the incoming filter () method. For example, to get all the four-letter languages starting with J, you can define two separate predicate examples to represent each condition, and then use the Predicate.and () method to merge them together, as follows:
// you can even merge predicate with and (), or (), and XOR () logic functions. // For example, to find all names starting with J with a length of four letters, you can merge two predicate and pass in predicate<string> startswithj = (n), N.startswith ("J"); predicate<String> Fourletterlong = (n)-n.length () = =4-System.out.print ("Nname, which Starts with ' J ' and four letter long is: "+ N)";
Similarly, the OR () and XOR () methods can also be used. This example focuses on the following points: You can use predicate as a separate condition and then combine it as needed. In short, you can use the predicate interface as a traditional Java command, or you can take advantage of lambda expressions to achieve a multiplier effect.
Example 6, map and reduce examples using lambda expressions in Java 8
This example introduces the most well-known functional programming concept map. It allows you to convert an object. For example, in this example, we convert each element of the Costbeforetax list into a value after tax. We upload the X-x*x lambda expression to the map () method, which applies it to each element in the flow. The list elements are then printed out with ForEach (). With the collector class of the stream API, you can get all the overhead of including taxes. A method such as ToList () merges the results of a map or any other operation. Since the collector does terminal operations on the stream, it cannot then reuse the stream. You can even synthesize all the numbers using the reduce () method of the stream API, as the next example will cover.
// do not use lambda expressions to add a 12% tax to each order List Costbeforetax = arrays.aslist (+, +, +, +); for (Integer cost:costbeforetax) {double price = Cost +. 12* cost; SYSTEM.OUT.PRINTLN (price);} // using lambda expressions List Costbeforetax = arrays.aslist (+, +, (+), +---+ cost +. 12*cost). ForEach (System.out::p rintln);
Output:
112.0
224.0
336.0
448.0
560.0
112.0
224.0
336.0
448.0
560.0
Example 6.2, map and reduce examples using lambda expressions in Java 8
In the previous example, you can see that the map transforms the collection class (such as a list) element. There is also a reduce () function that can combine all the values into one. The map and reduce operations are the core operations of functional programming, and because of their functionality, reduce is also known as collapsing operations. In addition, reduce is not a new operation and you may already be using it. The aggregate function in SQL that resembles sum (), AVG (), or count () is actually a reduce operation because they receive multiple values and return a value. The REDUCEH () function defined by the stream API can accept a lambda expression and merge all values. A class such as Intstream has built-in methods like average (), count (), sum () to do the reduce operation, and there are Maptolong (), Maptodouble () methods to do the conversion. This does not limit you, you can use the built-in method, or you can define it yourself. In this Java 8 map Reduce example, we first apply a 12% VAT to all prices and then use the reduce () method to calculate the sum.
//Add a 12% tax to each order//Old method:List costbeforetax = arrays.aslist (100, 200, 300, 400, 500);DoubleTotal = 0; for(Integer cost:costbeforetax) {DoublePrice = Cost +. 12*Cost;total= Total +Price ;} System.out.println ("Total:" +Total );//New method:List costbeforetax = arrays.aslist (100, 200, 300, 400, 500);DoubleBill = 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
Example 7, creating a string list by filtering
Filtering is a common practice for Java developers on large-scale collections, and now filtering large-scale data collections using lambda expressions and streaming APIs is surprisingly simple. The stream provides a filter () method that accepts a predicate object that can pass in a lambda expression as the filtering logic. The following example is to filter the Java collection with a lambda expression, which will help understand.
// Create a list of strings with each string longer 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]
In addition, there is a common misconception about the filter () method. In real life, filtering is usually discarded, but using the filter () method is a new list, and each of its elements conforms to the filtering principle.
Example 8, applying a function to each element of a list
We usually need to use a function for each element of the list, such as multiplying by a number, dividing by a number, or doing other things. These operations are well suited to the map () method, where the transformation logic can be placed in the form of a lambda expression in the map () method, and the individual elements of the collection can be converted, 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"= G7.stream (). Map (X-x.touppercase ()). Collect (Collectors.joining (",")); System.out.println (g7countries);
Output:
USA, JAPAN, FRANCE, Germany, ITALY, U.K., CANADA
Example 9, copy a different value, create a sub-list
This example shows how to use the distinct () method of a stream to de-weight a collection.
// Create a square list with all the different numbers list<integer> numbers = arrays.aslist (9, 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, 3, 4, 7, 3, 4], Square without duplicates: [81, 100, 9, 16, 49]
Example 10, calculating the maximum, minimum, sum, and average values of a SET element
There is a very useful method called Summarystatistics () in a class of streams such as
Intstream, Longstream, and Doublestream. You can return intsummarystatistics, Longsummarystatistics, or doublesummarystatistic s, which describe various summary data for the elements in the stream. In this example, we use this method to calculate the maximum and minimum values for the list. It also has the getsum () and Getaverage () methods to get the sum and average of all the elements of the list.
// gets the number, minimum, maximum, sum, and average values of numbers List<integer> primes = arrays.aslist (2, 3, 5, 7, one, A,, A,)= 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
Lambda Expressions vs Anonymous Classes
Since lambda expressions are about to formally replace anonymous inner classes in Java code, it is necessary to do a comparative analysis of both. A key difference is the keyword this. The This keyword of the anonymous class points to the anonymous class, and the This keyword of the lambda expression points to the class that encloses the lambda expression. Another difference is the way they are compiled. The Java compiler compiles a lambda expression into a private method of the class. This method is dynamically bound using the Java 7 invokedynamic bytecode directive.
Java 8 lambda expression essentials
10 Java lambda expressions, streaming API examples
So far we've seen the 10 lambda expressions in Java 8, which is a good task for newbies, and you may need to run the sample program yourself to get the job done. Try to modify the requirements to create your own examples, to achieve the purpose of rapid learning. I also want to suggest that you use the NetBeans IDE to practice lambda expressions, which support Java 8 well. When you convert the code into a functional form, NetBeans will prompt you. You can easily convert an anonymous class to a lambda expression simply by following NetBeans's hints. In addition, if you like reading, then remember to look at Java 8 Lambdas, practical functional Programming This book (Java 8 Lambdas, pragmatic functional programming), the author is Richard Warburton, Or you can look at Manning's Java 8 combat (Java 8 in Action), although this book is not yet published, but I guess there is a free PDF of the first chapter on the line. But before you start doing anything else, look back at the key knowledge of the lambda expressions, default methods, and functional interfaces of Java 8.
1) The lambda expression can only be placed in the following code: A predefined function interface that uses @Functional annotations, a method that comes with an abstract function, or a SAM (single abstract method) type. These target types, called lambda expressions, can be used as return types, or as parameters to the lambda target code. For example, if a method receives a runnable, comparable, or callable interface, there is a single abstract method that can be passed into a lambda expression. Similarly, if a method accepts an interface that is declared within a java.util.function package, such as predicate, function, Consumer, or Supplier, you can pass a lambda expression to it.
2) A method reference can be used within a lambda expression only if the method does not modify the parameters provided by the lambda expression. The lambda expression in this example can be swapped for a method reference, because this is only a simple method call with the same parameter.
List.foreach (n-System.out.println (n));
List.foreach (System.out::p rintln); Using method references
However, if you have any modifications to the parameters, you cannot use a method reference, and you need to type the full lambda expression as follows:
List.foreach (String s), System.out.println ("*" + S + "*"));
In fact, you can omit the type declaration of the lambda parameter here, which the compiler can infer from the class properties of the list.
3) Inside lambda you can use static, non-static, and local variables, which are called variable captures within a lambda.
4) lambda expressions are also called closures or anonymous functions in Java, so don't be surprised if a colleague calls it a closure.
5) The Lambda method is translated into a private method within the compiler and distributed with a invokedynamic bytecode instruction for invocation. You can use the JAVAP tool in the JDK to decompile the class file. Take a look at the bytecode generated by the lambda expression using the javap-p or javap-c-v command. It should generally look like this:
private static Java.lang.Object lambda$0 (java.lang.String);
6) lambda expressions have a limitation that only final or final local variables can be referenced, which means that variables defined outside the domain cannot be modified inside a lambda.
List<integer> primes = arrays.aslist (new integer[]{2, 3,5,7});
int factor = 2;
Primes.foreach (element, {factor++;});
Compile time error: "Local variables referenced from a lambda expression must is final or effectively final"
In addition, it is possible to simply access it without modification, as follows:
List<integer> primes = arrays.aslist (new integer[]{2, 3,5,7});
int factor = 2;
Primes.foreach (element, {System.out.println (factor*element);});
Output:
4
6
10
14
Therefore, it looks more like a non-variable closure, similar to Python.
These are all 10 examples of lambda expressions in Java 8. This change will be the largest in Java history and will have a profound impact on the way in which future Java developers use the collection framework. I think the most similar revision of the scale is the release of Java 5, which brings many advantages, such as: Generics, enumerations, auto-boxing (autoboxing), static import, concurrency APIs, and variable parameters. The above features make the Java code clearer, and I think the lambda expression will further refine it. I'm looking forward to developing parallel third-party libraries that make high-performance applications easier to write.
Java8 lambda expression 10 examples