"Java8 lambda expression 10 examples"

Java 8 was released just a few weeks ago on March 18, 2014, and this groundbreaking release has sparked a lot of discussion and excitement in the Java community. One of the features is the accompanying lambda expression, which will allow us to pass behavior into the function. Before Java 8, if you wanted to pass behavior into a function, the only option was an anonymous class, which required 6 lines of code. The line of code that defines the most important behavior is not prominent enough in the middle. Lambda expressions replace anonymous classes, do away with templates, and allow code to be written in a functional style. This is sometimes more readable and expresses clearer. In the Java ecosystem, functional expression and full support for object orientation are exciting advancements. It will further promote the development of parallel third-party libraries to take full advantage of multi-core CPUs. Although it will take time for the industry to digest Java 8, I don't think any serious Java developer should ignore the core features of this Java release, namely lambda expressions, functional interfaces, streaming APIs, default methods and the new Date and Time API. As a developer, I've found that the best way to learn and master lambda expressions is to be adventurous and practice as many lambda expression examples as possible. Given that the Java Collections framework was most affected by the release of Java 8, it's a good idea to practice streaming APIs and lambda expressions for extracting, filtering, and sorting Lists and Collections data. I've been writing about Java 8 and have shared some resources in the past to help you master Java 8. This article shares the use of 10 most useful lambda expressions in code. These examples are short and concise, and will help you quickly learn lambda expressions.

Java 8 lambda expression example
I'm personally very excited about the Java 8 release, especially the lambda expressions and streaming API. The more I know about them, the cleaner I can write. Although it wasn't like that at first. The first time I saw Java code written in lambda expressions, I was very disappointed with the arcane syntax, thinking they made Java unreadable, but I was wrong. After spending a day practicing with some lambda expressions and streaming API examples, I was happy to see cleaner Java code. It's a bit like learning about generics, and I hated it the first time I saw it. I even continued to use old Java 1.4 for collections until one day a friend introduced me to the benefits of using generics (and didn't realize it). So the basic stance is, don't be afraid of the cryptic syntax of lambda expressions and method references, after a few exercises, extracting and filtering data from collection classes, you'll love it. Let's start the learning journey of learning Java 8 lambda expressions, starting with a simple example.

Example 1. Implementing Runnable with lambda expressions
When I started using Java 8, the first thing I did was to replace anonymous classes with lambda expressions, and implementing the Runnable interface is the best example of an anonymous class. Take a look at the pre-Java 8 implementation of runnable, which requires 4 lines of code, while using lambda expressions requires only one line of code. What are we doing here? That is to replace the entire anonymous class with the () -> {} block.

// 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 way:
new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
Output:
too much code, for too little to do
Lambda expression rocks !!
This example shows us the syntax of Java 8 lambda expressions. You can use lambdas to write code like this:
(params) -> expression
(params) -> statement
(params) -> { statements }
For example, if your method doesn't modify or override parameters, it just prints something to the console If your method accepts two parameters, you can write it like this: ( int even, int odd) -> even
+ odd By the way, it's common to make the names of variables inside lambda expressions shorter. This keeps the code shorter and on the same line. Therefore, in the above code, it is better to choose a, b or x, y for the variable name than even and odd. Example 2. Event handling using Java 8 lambda expressions





If you've programmed with the Swing API, you'll remember how to write event listener code. This is again a classic use case of a simple anonymous class in the old version, but now it can be done otherwise. You can write better event listener code with lambda expressions like this:
// 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 way:
show.addActionListener((e) -> {
    System.out.println("Light , Camera, Action !! Lambda expressions Rocks");
});
Another place Java developers often use anonymous classes is for Collections. sort() Custom Comparator. In Java 8, you can swap out ugly anonymous classes with more readable lambda expressions. I'll leave this as an exercise, it shouldn't be difficult, and can be done as I did in the process of implementing Runnable and ActionListener using lambda expressions.

Example 3. Iterating over a list using a lambda expression
If you've been in Java for a few years, you know that the most common operation with collection classes is to iterate and apply business logic to individual elements, such as processing lists of orders, transactions, and events. Since Java is an imperative language, all loop code prior to Java 8 was sequential, i.e. its elements could be parallelized. If you want to do parallel filtering, you need to write the code yourself, which is not that easy. By introducing lambda expressions and default methods, the question of what to do and how to do it is separated, which means that Java collections now know how to iterate and can parallelize collection elements at the API level. In the following example, I'll show how to iterate over a list with or without a lambda expression. You can see that the list now has a forEach() method that iterates over all 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");
features.forEach(n -> System.out.println (n));



features.forEach(System.out::println);
Output:
Lambdas
Default Method
Stream API
Date and Time API
List loop The last example of looping shows how to use method references in Java 8. You can see that the double colon, scope resolution operator in C++ is now used in Java 8 to represent method references.

Example 4. Using lambda expressions and functional interface Predicate
In addition to supporting functional programming style at the language level, Java 8 also added a package called java.util.function. It contains many classes to support functional programming in Java. One of them is Predicate. Using the java.util.function.Predicate functional interface and lambda expressions, you can add logic to API methods to support more dynamic behaviors with less code. Below is an example of a Java 8 Predicate that shows several common ways to filter collection data. The Predicate interface is very useful for filtering.
public static void main(args[]){
    List languages ​​= Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");

    System.out.println("Languages ​​which starts with J :");
    filter(languages,

    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 + " ");
    }) ;
}
As you can see, the filter method of the Stream API 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 lambda expressions. In addition, the Predicate interface also allows testing of multiple conditions, as will be discussed in the next example.

Example 5. How to add Predicate in lambda expression The
previous example mentioned that java.util.function.Predicate allows two or more Predicates to be combined into one. It provides methods similar to the logical operators AND and OR, named and(), or(), and xor(), for combining the conditions passed to the filter() method. For example, to get all four-letter languages ​​that start with J, you can define two separate Predicate instances for each condition, and combine them with the Predicate.and() method, as follows:
// You can even combine Predicates with and(), or() and xor() logical functions,
// for example to find all names starting with J and having a length of four letters, you can combine two Predicates and pass 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));
Similarly, the or() and xor() methods can also be used. This example highlights the point that Predicates can be used as separate conditions and then combined as needed. In short, you can use the Predicate interface in the traditional Java imperative way, or you can take advantage of lambda expressions to do more with less.

Example 6. Map and Reduce example using lambda expressions in Java 8
This example introduces the most well-known functional programming concept map. It allows you to convert objects. For example, in this example, we convert each element of the costBeforeTax list to a value after tax. We pass the x -> x*x lambda expression to the map() method, which applies it to every element in the stream. Then use forEach() to print the list elements. Using the collector class of the Streaming API, you can get all the tax-included overhead. There are methods like toList() that combine the results of a map or any other operation. Since the collector does terminal operations on the stream, the stream cannot be reused later. You can even combine all the numbers into one using the reduce() method of the Streaming API, which will be covered in the next example.
// Add 12% tax to each order without lambda expression
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
for (Integer cost : costBeforeTax) {
    double price = cost + .12 *cost;
    System.out.println(price);
}

// use lambda expression
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
Example 6.2, Map and Reduce example using lambda expressions in Java 8
In the previous example, you can see that map transforms the elements of a collection class (such as a list). There is also a reduce() function to combine all values ​​into one. Map and Reduce operations are the core operations of functional programming, and because of its functionality, reduce is also known as a folding operation. Also, 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 take multiple values ​​and return a single value. The reduce() function defined by the streaming API can accept a lambda expression and combine all values. Classes like IntStream have built-in methods like average(), count(), and sum() for reduce operations, as well as mapToLong() and mapToDouble() methods for conversion. This doesn't limit you, you can use built-in methods or define your own. 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 12% tax to each order
// Old way:
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
Example 7. Create a String list by
filtering Filtering is a large-scale collection of Java developers It is now surprisingly easy to filter large collections of data using lambda expressions and streaming APIs. The stream provides a filter() method that accepts a Predicate object, that is, a lambda expression can be passed in as the filtering logic. The following example of filtering a Java collection with lambda expression will help to 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]
Also, there is a common misconception about the filter() method. In real life, when filtering, parts are usually discarded, but with the filter() method, a new list is obtained, and each element of it conforms to the filtering principle.

Example 8. Applying a function to each element of a list
We usually need to apply a function to each element of a list, such as multiplying a number one by one, dividing by a number, or doing other operations. These operations are all suitable for using the map() method. You can put the conversion logic in the map() method in the form of a lambda expression to convert each element of the collection, as shown below.
// Convert strings to uppercase and chain them with commas
List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy", "UK","Canada") ;
String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
System.out.println(G7Countries);
output:
USA, JAPAN, FRANCE , GERMANY, ITALY, UK,
CANADA Example 9. Copying different values, creating a sublist
This example shows how to use the distinct() method of a stream to deduplicate a collection.
// create a list of squares 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]
Example 10. Calculating the maximum, minimum, sum and average of set elements
Classes of streams such as IntStream, LongStream and DoubleStream , there is a very useful method called summaryStatistics(). Can return IntSummaryStatistics, LongSummaryStatistics, or DoubleSummaryStatistics, describing various summary data for elements in the stream. In this example, we use this method to calculate the maximum and minimum values ​​of a list. It also has getSum() and getAverage() methods to get the sum and average of all elements of the list.
//Get the number, min, max, 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());
输出:
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表达式 vs 匿名类
Now that lambda expressions are about to officially replace anonymous inner classes in Java code, it is necessary to make a comparative analysis of the two. A key difference is the keyword this. The this keyword of an anonymous class points to the anonymous class, and the this keyword of a lambda expression points to the class that encloses the lambda expression. Another difference is how the two are compiled. The Java compiler compiles lambda expressions into private methods of the class. This method is dynamically bound using the Java 7 invokedynamic bytecode instruction.

Java 8 Lambda Expressions Essentials
10 Java Lambda Expressions, Streaming API Examples We have seen 10 Java 8 lambda expressions
so far , which is a decent amount of work for newbies, you may need to run the sample programs yourself in order to master. Try to modify the requirements to create your own examples for quick learning. I would also like to suggest that you use Netbeans IDE to practice lambda expressions, it has good Java 8 support. When converting code to functional, Netbeans will prompt you in time. It's easy to convert an anonymous class into a lambda expression just by following the Netbeans tips. Also, if you like reading, then remember to check out Java 8 lambdas, pragmatic functional programming by Richard Warburton, or Manning's Java 8 in action (Java 8 Lambdas, pragmatic functional programming) 8 in Action), the book isn't out yet, but I guess there is a free pdf of the first chapter online. However, before you get into anything else, let's review the key points of Java 8's lambda expressions, default methods, and functional interfaces.

1) lambda expressions can only be placed in the following code: predefined functional interfaces annotated with @Functional, methods with an abstract function, or SAM (Single Abstract Method) type. These are called target types of lambda expressions, and can be used as return types, or as arguments to lambda target code. For example, if a method accepts a Runnable, Comparable, or Callable interface, there is a single abstract method that can be passed in a lambda expression. Similarly, if a method accepts an interface declared in the java.util.function package, such as Predicate, Function, Consumer or Supplier, it can be passed a lambda expression.

2) A method reference can be used inside 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 replaced by a method reference, since this is just a simple method call with the same parameters.

list.forEach(n -> System.out.println(n)); list.forEach
(System.out::println); // use a method reference
The complete lambda expression needs to be typed as follows:
list.forEach((String s) -> System.out.println("*" + s + "*"));
In fact, the type declaration of the lambda parameter here can be omitted, and the compiler can infer it from the class attribute of the list.

3) Static, non-static and local variables can be used inside lambda, which is called variable capture inside lambda.

4) Lambda expressions are also called closures or anonymous functions in Java, so don’t be surprised if some colleagues call it a closure.

5) Lambda methods are translated into private methods inside the compiler, and invokedynamic bytecode instructions are dispatched for invocation. Class files can be decompiled using the javap tool in the JDK. Use the javap -p or javap -c -v commands to see the bytecode generated by the lambda expression. It should roughly look like this:

private static java.lang.Object lambda$0(java.lang.String);
6) lambda expressions have a limitation, that is, only final or final local variables can be referenced, which means that they cannot be modified inside the lambda Variables defined outside the domain.

List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
int factor = 2;
primes.forEach(element -> { factor++; });
1
Compile time error : "local variables referenced from a lambda expression must be final or effectively final"
Also, it's OK to just access it without modification, like this:

List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5, 7});
int factor = 2;
primes.forEach(element -> { System.out.println(factor*element); });
Output:
So it looks more like an immutable closure, similar to Python.

That's all 10 examples of lambda expressions in Java 8. This revision will be the largest in Java history and will have a profound impact on the way Java developers use the collections framework in the future. I think one of the most similar changes in scale was the release of Java 5, which brought many advantages and improved code quality such as: Generics, Enums, Autoboxing, Static Imports, Concurrency API, and Variable Parameters . The above features make the Java code much cleaner and I think lambda expressions will improve it further. I'm looking forward to developing parallel third-party libraries that can make high-performance applications easier to write.

More reading: http://javarevisited.blogspot.com/2014/02/10-example-of-lambda-expressions-in-java8.html#ixzz3gCMp6Vhc

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326268095&siteId=291194637