Detailed explanation of lambda expression example, a new feature of Java 8

Detailed explanation of lambda expression example, a new feature of Java 8

Before introducing lambda expressions, let's first look at the interface with only a single method (commonly known as callback interface):

We use it this way:

This callback mode is very popular in various frameworks, but anonymous inner classes like the above are not a good choice because:

Happily, Java 8 has brought us lambda. Let's see how to use lambda to realize the above functions:

how?! Five lines of code is done in one line!!!

A conceptual functional interface is added here; The onclicklistener interface mentioned earlier has only one method. Most callback interfaces in java have this feature: such as runnable and comparator; We call these interfaces with only one method functional interfaces.

1、 Lambda expression

The biggest problem with anonymous inner classes is their redundant syntax. For example, in the previous onclicklistener, only one of the five lines of code is executing tasks. Lambda expressions are anonymous methods, and we saw earlier that they solve this problem with extremely lightweight syntax.

Here are some examples of lambda expressions:

Lambda expression syntax consists of parameter list, - > and function body. The function body can be either an expression or a code block.

Expression: the expression is executed and the result is returned. It simplifies the return keyword.

Code block: as the name suggests, it is a lump of code, just like the statements in ordinary methods.

2、 Target type

From the previous example, we can see that the lambda expression has no name, so how do we know its type? The answer is derived from context. For example, the type of the following expression is onclicklistener

This means that the same lambda expression has different types in different contexts

The compiler uses the expected type in the context of the lambda expression to deduce the type of the expression. This expected type is called the target type. Lambda expressions can only appear in a context where the target type is a functional interface.

The type of lambda expression and the method signature of the target type must be consistent, which will be checked by the compiler. To assign a lambda expression to the target type T, all the following conditions must be met:

Since the target type is the parameter type of the lambda expression, we don't need to repeat the known types. That is, the parameter type of lambda expression can be obtained from the target type:

PS: generic methods and < > constructors in Java 7 are also derived from the target type, such as:

3、 Scope

Using variable names and this in internal classes is very error prone. The member variables of the internal class obtained through inheritance (including those of object) may overwrite the member variables of the external class, and the unrestricted this reference will point to the internal class itself rather than the external class.

The semantics of a lambda expression is very simple: it does not inherit any variables from the parent class, nor does it introduce a new scope. The parameters of a lambda expression and the variables in the function body have the same semantics as the variables in its external environment (the same is true for this keyword).

Let's take a chestnut!

The above code will eventually print two Hello, lambda!, Similar inner classes will print hellolambda$ 1@32a890 And hello lambda$ 1@6b32098 This unexpected string.

Summary: Based on the concept of lexical scope, lambda expressions can not cover up any local variables in their context.

4、 Variable capture

In Java 7, The compiler has very strict requirements for external variables (i.e. captured variables) referenced in internal classes: if the captured variables are not declared final, a compilation error will be generated. However, this restriction is relaxed in Java 8. C. for lambda expressions and internal classes, it is allowed to capture local variables that comply with valid read-only (if a local variable has never been modified after initialization, it is valid read-only).

References to this, references to unqualified fields and calls to unqualified methods through this are essentially the use of final local variables. A lambda expression containing such a reference is equivalent to capturing this instance. In other cases, lambda objects do not retain any application of this.

This feature is excellent for memory management: you should know that in Java, a non static internal class will hold strong references to external class instances by default, which often leads to memory leakage. If the external class member is not captured in the lambda expression, the reference to the external class instance will not be retained.

However, although Java 8 has relaxed the syntax restrictions on captured variables, attempts to modify captured variables are prohibited. For example, the following example is illegal:

Why prohibit such behavior? Because such lambda expressions can easily cause race conditions

Another reason why lambda expressions do not support modifying capture variables is that we can achieve the same effect in a better way: using conditions. java. util. The stream package provides various specification operations. We will introduce the stream API in Java 8 in the next chapter.

5、 Method reference

Lambda expressions allow us to define an anonymous method and use it as a functional interface. Java 8 can implement the same features on existing methods.

Method references and lambda expressions have the same characteristics (they both need a target type and need to be converted into instances of functional interfaces). However, we do not need to provide method bodies for method references. We can directly reference existing methods through method names.

Take the following code as an example, suppose we want to sort by username

We can replace the above lambda expression with a method reference

Here, user:: GetUserName is regarded as a short form of lambda expression. Although method reference does not necessarily make the code more compact, it has clearer semantics. C. if the method we want to call has a name, we can call it through the method name.

There are many kinds of method references, and their syntax is as follows:

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>