Java 8 is called the most changed version in Java history. It contains many important new features, the most core is the addition of Lambda expressions and StreamAPI. The two can also be used together. First, let’s take a look at what is a Lambda expression.
Using Lambda expressions not only makes the code simple, but also readable, and most importantly, the amount of code also decreases a lot. However, to some extent, these functions have been widely used in JVM languages such as Scala.
Not surprisingly, the Scala community is incredible, because a lot of Java 8 content looks like it was moved from Scala. To some extent, Java 8's syntax is more detailed but not very clear than Scala's, but that doesn't say much, and if it can, it might build Lambda expressions like Scala does.
On the one hand, if Java continues to develop and implement functions that Scala has already implemented around Lambda, then Scala may not be needed. On the other hand, if it only provides some core features, such as helping anonymous internal classes, Scala and other languages will continue to thrive and may overtake Java. In fact, this is the best result. Only with competition can there be progress. Other languages continue to develop and grow, and there is no need to worry about whether they will be outdated.
Lambda expression, the explanation on Wikipedia is an operator used to represent anonymous functions and closures. I feel that this explanation is still very abstract. Let's look at an example.
public class SwingTest { public static void main(String[] args) { JFrame jFrame = new JFrame("My JFrame"); JButton jButton = new JButton("My JButton"); jButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Button Pressed!"); } }); jFrame.add(jButton); jFrame.pack(); jFrame.setVisible(true); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }}This is a piece of code in Swing programming that binds a listening event to Button. When Button is clicked, the content "ButtonPressed!" will be output on the console. Here we create an instance of an anonymous inner class to bind to the listener, which is also a relatively common code organization form in the past. But if we look closely, we will find that in fact, what we are really focusing on is a parameter e of ActionEvent type and the statement System.out.println("ButtonPressed!"); output to the console.
If the code in the previous program that creates an anonymous internal class is replaced with a Lambda expression, the code is as follows
public class SwingTest {public static void main(String[] args) { JFrame jFrame = new JFrame("My JFrame"); JButton jButton = new JButton("My JButton"); jButton.addActionListener(e -> System.out.println("Button Pressed!")); jFrame.add(jButton); jFrame.pack(); jFrame.setVisible(true); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}} Pay attention to the changes in the middle part of the code, from the original 6 lines of code, now 1 line can be implemented. This is a simple form of Lambda expression.
It can be seen that the syntax of Lambda expression is
(param1,param2,param3) -> {//todo}The type program of the parameter here can be inferred based on the context, but not all types can be inferred. At this time, we need to display the declared parameter type. When there is only one parameter, the brackets can be omitted. When the todo part has only one line of code, the braces on the outside can be omitted. As in our example above
So in addition to the concise code, does Lambda expression bring us any changes?
Let's recall that in Java, we cannot pass a function as a parameter to a method, nor can we declare that the return value is a method of a function. Before Java 8, the answer was yes.
So, in the above example, we can actually pass a piece of code logic as a parameter to the listener, telling the listener that you can do this when the event is triggered, without the need to use anonymous internal classes as parameters. This is also another new feature brought by Java 8: functional programming.
There are many languages that support functional programming. In JavaScript, it is very common to pass functions as parameters or return values as functions. JavaScript is a very common functional language.
Lambda adds missing functional programming features to Java, allowing us to treat functions as first-class citizens.
In functional programming languages, the type of a Lambda expression is a function. In Java, Lambda expressions are objects, and they must be attached to a special object type - Functional Interface.
Next, let's look at the definition of the functional interface:
If there is and only one abstract method in an interface (the methods in the Object class are not included), then this interface can be regarded as a functional interface.
@FunctionalInterfacepublic interface Runnable { /** * When an object implementing interface <code>Runnable</code> is used * to create a thread, starting the thread causes the object's * <code>run</code> method to be called in that separately executing * thread. * <p> * The general contract of the method <code>run</code> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run();}Let’s take a look at the statement of the Runnable interface. After Java 8, the Runnable interface has an additional FunctionalInterface annotation, indicating that the interface is a functional interface. However, if we do not add FunctionalInterface annotation, if there is and only one abstract method in the interface, the compiler will also regard the interface as a functional interface.
@FunctionalInterfacepublic interface MyInterface { void test(); String toString();}MyInterface is also a functional interface, because toString() is a method in the Object class, but it is rewrited here and will not increase the number of abstract methods in the interface.
(To mention here, in Java 8, the methods in the interface can not only have abstract methods, but also have specific implemented methods. They are called default methods, which will be introduced in detail later)
Since in Java, Lambda expressions are objects. So what is the type of this object? Let's review the SwingTest program, where an ActionListener interface instance is created in an anonymous internal class.
jButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("Button Pressed!"); } });Improved with Lambda expression
jButton.addActionListener(e -> System.out.println("Button Pressed!"));That is, we use Lambda expression to create an instance of the ActionListener interface, and then look at the definition of the ActionListener interface.
public interface ActionListener extends EventListener { /** * Invoked when an action occurs. */ public void actionPerformed(ActionEvent e);} There is only one abstract method. Although the FunctionalInterface annotation is not added, it also conforms to the definition of a functional interface. The compiler will consider this to be a functional interface.
Therefore, using Lambda expressions can create instances of functional interfaces. That is, the Lambda expression returns a functional interface type.
In fact, there are three ways to create functional interface instances (refer to the FunctionalInterface annotation):
1. Lambda expressions
2. Method citation
3. Constructor method reference
Summarize
The above is all about this article about Java 8's simple understanding of Lambda expressions and functional interfaces. I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out!