Java: article master Lambda expressions

This article introduces the Java 8 new Lambda expressions, including the use of common usage, and methods Lambda expressions of reference, and analyzes the principle Lambda expressions, the last of the advantages and disadvantages of Lambda expressions are a summary.

 

 

 

1 Overview

Lambda expressions Java main role is to simplify the wording introduced in 8 portions anonymous inner classes.

Be able to use an important basis Lambda expressions must have the appropriate function interface. The so-called function interface, and only refers to the internal interface of the abstract method.

Lambda expressions are based on another type inference mechanism. In the context information is sufficient, the compiler can infer the type of the parameter table, without the need for an explicit name.

2. Common usage

2.1 no-argument function shorthand

No reference function is a function of no arguments, for example,  Runnable the interface  run() method, which is defined as follows:

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

In Java 7 and earlier, we generally use:

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello");
        System.out.println("Jimmy");
    }
}).start();

8 starting from Java, not anonymous inner classes may be abbreviated as function parameters in the following manner:

()

() -> { 
    execute statement 
}

Such interfaces and function names can be missed. Then, the above example can be abbreviated as:

new Thread(() -> {
    System.out.println("Hello");
    System.out.println("Jimmy");
}).start();

When only one statement, we can also shorthand code block, the following format:

() -> Expressions

Note the use of an expression, not a statement, that does not require a semicolon at the end.

Then, when only one when the statement is executed in the above example, this may be abbreviated as:

new Thread(() -> System.out.println("Hello")).start();

2.2 Single shorthand reference function

Unary function is a function of only one parameter. For example,  View the interface interior of  OnClickListener the method  onClick(View v), which is defined as follows:

public interface OnClickListener {
    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    void onClick(View v);

7 and earlier versions of Java, we usually use might be so:

view.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        v.setVisibility(View.GONE);
    }
});

Java 8 from the start, anonymous inner classes unary function may be abbreviated as follows:

([Class name] variable name) -> { 
execute statement 
}

Where the class name is omitted, because Lambda expressions can be inferred own. Then the above example can be abbreviated into the following two ways:

view.setOnClickListener((View v) -> {
v.setVisibility(View.GONE);
});
view.setOnClickListener((v) -> {
v.setVisibility(View.GONE);
});

Unary function can even remove the brackets, the government has also recommended more use in this way:

Variable name -> { 
execute statement 
}

Then, the above example can be abbreviated as:

view.setOnClickListener(v -> {
v.setVisibility(View.GONE);
});

When only one statement, the code can still be short block, the following format:

([Class name] variable name) -> Expression
1
class name and the brackets can still be omitted, as follows:

Variable name -> expression
1
then, the above example can be further simplified into:

view.setOnClickListener(v -> v.setVisibility(View.GONE));

Over 2.3 shorthand reference function

Multi-parameter functions are functions having two or more parameters. For example, Comparator compare (T o1, T o2) method on the interface has two parameters, which are defined as follows:

FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}

7 and earlier versions of Java, when we sort a collection, you can usually write:

List<Integer> list = Arrays.asList(1, 2, 3);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});

Starting Java 8, anonymous inner classes multi-parameter function may be abbreviated as follows:

([Class name 1] variable name 1, [name of the class 2] variable name 2 [, ...]) -> {
execute statement
}
same class name can be omitted, the above example can be abbreviated as:

Collections.sort(list, (Integer o1, Integer o2) -> {
return o1.compareTo(o2);
});
Collections.sort(list, (o1, o2) -> {
return o1.compareTo(o2);
});

When only one statement, the code can still be short block, the following format:

([Class name 1] variable name 1, [name of the class 2] variable name 2 [, ...]) -> Expression
1
at this time is the class name can be omitted, but the brackets can not be omitted. If this statement needs to return a value, then the return keyword is not required to write.

Thus, the above example can be further simplified into:

Collections.sort(list, (o1, o2) -> o1.compareTo(o2));

Finally it, this example also can be abbreviated like this:

Collections.sort(list, Integer::compareTo);

Hey, what is this characteristic? That's us talk about the following contents: reference method.

 

   I believe many people have problems and bottlenecks in the fourth year of front-end or mid-time will always be, as some time learning not get no sense of direction or a boring person to learn how to solve a problem do not know, I am finishing up I want to get some information, then more knowledge and enhance learning and want to discuss with the more experienced Daniel welcome to join my group study exchange 907 694 362

 

3. The method references

The method also references a syntactic sugar, it can be used to simplify development.

When we use Lambda expressions, if the "->" expression on the right to execute just call a method of a class already, then it can be replaced Lambda expressions "reference method" used.

Reference method can be divided into four categories:

Refer to a static method;
method of the referenced object;
a reference class;
reference constructor.
The following four categories are set forth in accordance with, respectively.

3.1 reference a static method

When the expression we want to do is call the static method of a class, and the list of parameters and interfaces parameter list in the function of this abstract static method of correspondence, we can refer to a static method of using the format.

If Lambda expressions that conform to the following format:

. ([Variable 1, variable 2, ...]) -> static method name class name ([variable 1, variable 2, ...])
we can be abbreviated to the following format:

Class name :: static method name
Note that static methods do not need parentheses behind the name, do not add parameters because the compiler can be inferred. Let's continue to use the example to be described in Section 2.3.

First create a utility class code is as follows:

public class Utils {
public static int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
}

Note here compare () parameters and compare parameters Comparable interface function () function is a one to one. Then the general Lambda expressions can be written:

Collections.sort(list, (o1, o2) -> Utils.compare(o1, o2));

If the reference of the method employed, this may be abbreviated as:

Collections.sort(list, Utils::compare);

Methods 3.2 object reference

When the expression we want to do is call an object's method, and when the list of parameters and interfaces parameter list in the function of this abstract method of correspondence, we can format the object using a reference method.

If Lambda expressions that conform to the following format:

([Variable 1, variable 2, ...]) -> method name object reference ([variable 1, variable 2, ...]).
1
we can be abbreviated to the following format:

Object reference method name ::
1
Here we continue to use the example to be described in Section 2.3. First, create a class code is as follows:

public class MyClass {
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
}

When we create an object of the class, and use the object in Lambda expression method, generally you can write:

MyClass myClass = new MyClass();
Collections.sort(list, (o1, o2) -> myClass.compare(o1, o2));

Note that this parameter is a function of one to one, then the method by way of reference, this may be abbreviated:

MyClass myClass = new MyClass();
Collections.sort(list, myClass::compare);

In addition, when the expression we want to execute the method of the class is where the calls Lambda expressions, we can also use the following format:

this :: method name
, for example, I added the following method in class Lambda expressions are located:

private int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}

When Lambda expressions using this method, generally can be written:

Collections.sort(list, (o1, o2) -> compare(o1, o2));

If the reference of the method employed, this can be abbreviated as:

Collections.sort(list, this::compare);
private int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}

 

3.3 cited methods of the class

The method used in reference to the class corresponding to the form of the two kinds of parameters is slightly different. If Lambda expressions "->" expression to the right to be executed is called "->" argument an instance of the method of the first left, and start from the second parameter (or no parameters) corresponds to the when the parameter list examples of methods, this method can be used.

It may be a bit around, if we Lambda expressions that conform to the following format:

(1 variable [, variable 2, ...]) -> Variable 1. Examples of the method ([Variable 2, ...])
1
then we code can be abbreviated as:

Class name :: example of a method corresponding to a variable name
1
Examples section 2.3 is used when we used Lambda expressions is when:

Collections.sort(list, (o1, o2) -> o1.compareTo(o2));

According to the above statement, it can be abbreviated like this:

Collections.sort(list, Integer::compareTo);

3.4 reference constructor

When the expression when we want to do is create a new object, and the parameter list constructor of this object and a list of parameters in function interfaces-one correspondence, we can adopt "reference constructor" format.

If our Lambda expressions that conform to the following format:

([Variable 1, variable 2, ...]) -> new class name ([variable 1, variable 2, ...])
1
we can be abbreviated to the following format:

:: new class name
Here's an example to explain. Java 8 introduces a Function interface, which is a function of the interface, part of the code as follows:

@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
// 省略部分代码
}

We use this interface to implement a function to create a specified size ArrayList. Generally, we can achieve this:

Function<Integer, ArrayList> function = new Function<Integer, ArrayList>() {
@Override
public ArrayList apply(Integer n) {
return new ArrayList(n);
}
};
List list = function.apply(10);


Use Lambda expressions, we generally can write:

Function<Integer, ArrayList> function = n -> new ArrayList(n);
1


Use "references constructor" approach, we can be abbreviated like this:

Function<Integer, ArrayList> function = ArrayList::new;

4. Custom function interface
custom function interface easily, only need to write only one interface to an abstract method, the sample code:

@FunctionalInterface
public interface MyInterface<T> {
void function(T t);
}

@FunctionalInterface above code is optional, but with the annotation compiler will help you check for compliance with the interface function interface specification. Like adding @Override comment function checks whether to rewrite the same.

5. The principle

After the above introduction, we see Lambda expressions only to simplify writing anonymous inner classes, seem to replace at compile all of Lambda expressions to anonymous inner classes on it. But the reality is not the case, the JVM level, Lambda expressions and anonymous inner classes in fact there is a clear difference.

Achieve 5.1 anonymous inner classes
Anonymous inner classes is still a class, we just do not need to explicitly specify the class name, the compiler will automatically for the class name. Such code has the following form:

public class LambdaTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello World");
}
}).start();
}
}

It will have two class files after compilation:

LambdaTest.class
LambdaTest$1.class
1
2

Further analysis using javap -c LambdaTest.class LambdaTest.class bytecode portion results are as follows:

public static void main(java.lang.String[]);
Code:
0: new #2 // class java/lang/Thread
3: dup
4: new #3 // class com/example/myapplication/lambda/LambdaTest$1
7: dup
8: invokespecial #4 // Method com/example/myapplication/lambda/LambdaTest$1."<init>":()V
11: invokespecial #5 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
14: invokevirtual #6 // Method java/lang/Thread.start:()V
17: return

It can be found in 4: new # 3 this line creates an object of an anonymous inner class.

Achieve 5.2 Lambda expressions

Next we will use the sample code above Lambda expressions to achieve, the following code:

public class LambdaTest {
public static void main(String[] args) {
new Thread(() -> System.out.println("Hello World")).start();
}
}

At this point the compiler will generate a file LambdaTest.class, look at the result of decompilation by javap the file:

ublic static void main(java.lang.String[]);
Code:
0: new #2 // class java/lang/Thread
3: dup
4: invokedynamic #3, 0 // InvokeDynamic #0:run:()Ljava/lang/Runnable;
9: invokespecial #4 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
12: invokevirtual #5 // Method java/lang/Thread.start:()V

 

We have found from the above results a private method of the main class Lambda expressions become encapsulated, and invoked through invokedynamic instruction.

Therefore, we can conclude: Lambda expressions are achieved by invokedynamic instruction, and writing Lambda expressions will not produce a new class.

Since the Lambda expression does not create an anonymous inner class, then use this keyword in Lambda expressions, it is a reference point outside the class.

6. pros and cons

advantage:

You can reduce the write code, reducing create anonymous inner classes, saving memory footprint.
Interfaces and abstract functions do not have to remember what you used to.
Disadvantages:

Legibility is poor, people need to be familiar with reading the code of the type of Lambda expressions and abstract function parameters.
Convenient debugging.

I believe many people have problems and bottlenecks in the fourth year of front-end or mid-time will always be, as some time learning not get no sense of direction or a boring person to learn how to solve a problem do not know, I am finishing up I want to get some information, then more knowledge and enhance learning and want to discuss with the more experienced Daniel welcome to join my group study exchange 907 694 362

 

Guess you like

Origin www.cnblogs.com/xsd1/p/11919482.html