Lambda best practices in Java 8 (1)
Java 8 has been launched for some time. More and more developers choose to upgrade JDK. The hot news shows that JDK 7 is the most popular, followed by JDK 6 and 8. This is a good thing!
In 8, Lambda is the most popular topic, not only because of changes in syntax, but more importantly, it brings the idea of functional programming. I think it is a good programmer, it is necessary to learn the idea of functional programming to broaden your mind. So this article will talk about Lambda's application scenarios, performance, and the negative side.
Why does Java require Lambda?
In January 1996, Java 1.0 was released. Since then, the computer programming field has undergone earth-shaking changes. Business development requires more complex applications, and most programs run on more powerful machines equipped with multi-core CPUs. The emergence of Java Virtual Machine JVM with efficient runtime compilers enables programmers to focus more on coding clean and easy to maintain code, instead of thinking about how to use every CPU clock and every byte of memory.
The emergence of multi-core CPU becomes "the elephant in the room", which cannot be ignored, but no one is willing to face up to it. The introduction of locks in algorithms is not only prone to errors, but also consumes time. Java. util. concurrent packages and many third-party class libraries have been developed to abstract concurrency and help programmers write programs that run well on multi-core CPUs. Unfortunately, we have not gone far enough until now.
When developers of those class libraries use Java, they find that the abstract level is not enough. Processing Big Data is a good example. In the face of big data, Java still lacks efficient parallel operations. Java 8 allows developers to write complex collection processing algorithms. By simply modifying a method, code can run efficiently on a multi-core CPU. To compile a class library for parallel processing of these big data, you need to modify the existing Java language: Add a lambda expression.
Of course, there is a price to do this. programmers must learn how to write and read code containing lambda expressions. However, this is not a financial loss. Compared with writing a large segment of complex, thread-safe code, it is much easier to learn a little new syntax and some new habits. When developing enterprise-level applications, good class libraries and frameworks greatly reduce development time and costs, and clear the obstacles to easy-to-use and efficient class libraries.
If you have not touched the Lambda syntax, you can refer to it here.
Lambda application scenarios
It is necessary for you to learn the concept of functional programming, such as a preliminary study of functional programming. However, I will focus on the practicality of functional programming, this includes technologies that can be understood and used by most programmers. We are concerned about how to write code well, rather than code that conforms to the functional programming style.
1. Replace the Anonymous class with ()-> {}
Now Runnable threads, Swing, JavaFX event listener code, etc. In java 8, you can use Lambda expressions to replace ugly anonymous classes.
- //Before Java 8:
- new Thread(new Runnable() {
- @Override
- public void run() {
- System.out.println("Before Java8 ");
- }
- }).start();
-
- //Java 8 way:
- new Thread(() -> System.out.println("In Java8!"));
-
- // Before Java 8:
- JButton show = new JButton("Show");
- show.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- System.out.println("without lambda expression is boring");
- }
- });
-
-
- // Java 8 way:
- show.addActionListener((e) -> {
- System.out.println("Action !! Lambda expressions Rocks");
- });
2. Replace the External Loop with an inner loop
External Loop: describes how to do it. More than two for loops nested in the Code are more difficult to understand. Only List elements can be processed in sequence;
Inner Loop: describes what to do, not how to do it; it is not necessary to process the elements in the List in sequence
- //Prior Java 8 :
- List features = Arrays.asList("Lambdas", "Default Method",
- "Stream API", "Date and Time API");
- for (String feature : features) {
- System.out.println(feature);
- }
-
- //In Java 8:
- List features = Arrays.asList("Lambdas", "Default Method", "Stream API",
- "Date and Time API");
- features.forEach(n -> System.out.println(n));
-
- // Even better use Method reference feature of Java 8
- // method reference is denoted by :: (double colon) operator
- // looks similar to score resolution operator of C++
- features.forEach(System.out::println);
-
- Output:
- Lambdas
- Default Method
- Stream API
- Date and Time API
3. Support for function Programming
To support function programming, Java 8 adds a new package of java. util. function, where java. util. function. Predicate is an interface that supports Lambda function programming:
- 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) {
- names.stream().filter((name) -> (condition.test(name)))
- .forEach((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
4. Processing Data? MPs queue is more concise
The Stream API added in Java 8 makes data processing in the set more convenient, with higher performance and better readability.
Assume a business scenario: perform a discount on goods of more than 20 yuan, and finally get the discount price for these goods.
- final BigDecimal totalOfDiscountedPrices = prices.stream()
- .filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0)
- .map(price -> price.multiply(BigDecimal.valueOf(0.9)))
- .reduce(BigDecimal.ZERO,BigDecimal::add);
-
- System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);
Imagine how many lines are required if Object-oriented Data is used? How many cycles? How many intermediate variables need to be declared?
For more information about Stream APIs, see my previous articles.