nsv_productdetail.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int bottomMargin = ((ViewGroup.MarginLayoutParams) nsv_productdetail.getLayoutParams()).bottomMargin;
nsv_productdetail.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
If the above code is converted into lambda, this will point to the external class, and the listener cannot be removed at this time.
So I would like to ask, how can an anonymous inner class (an anonymous inner class that can be converted to a lambda) obtain itself in the lambda?
Replace some anonymous inner classes
This section will introduce how to use Lambda expressions to simplify the writing of anonymous inner classes. However, Lambda expressions cannot replace all anonymous inner classes. They can only be used to replace the abbreviation of Functional Interface. . Don’t worry about the details yet, let’s look at a few examples.
Example 1: Abbreviation of parameterless function
If you need to create a new thread, a common way of writing it is like this:
// JDK7 anonymous inner class writing method
new Thread(new Runnable(){// interface name
}).start();
The above code passes an anonymous Runnable object to the Tread class, and overloads the run() method of the Runnable interface to implement the corresponding logic. This is a common way of writing in JDK7 and before. Anonymous inner classes save you the trouble of naming the class, but it is still not simple enough. In Java 8, it can be simplified to the following form:
// How to write JDK8 Lambda expression
new Thread(
).start();
The above code has the same function as the anonymous inner class, but it goes further than the anonymous inner class. Here the connection port name and function name are omitted together, making it more refreshing to write. If the function body has multiple lines, it can be enclosed in curly braces, like this:
// How to write JDK8 Lambda expression code block
new Thread(
).start();
Example 2: Abbreviation of function with parameters
If you want to pass a custom comparator to a string list and sort it according to the string length, the writing form of Java 7 is as follows:
// How to write anonymous inner classes in JDK7
List<String> list = Arrays.asList("I", "love", "you", "too");
Collections.sort(list, new Comparator<String>() {//Interface name
});
The above code overloads the compare() method of the Comparator interface through the internal class to implement comparison logic. Using Lambda expression can be abbreviated as follows:
// How to write JDK8 Lambda expression
List<String> list = Arrays.asList("I", "love", "you", "too");
Collections.sort(list, (s1, s2) -> ;{// Omit the type of parameter table
});
The above code has the same function as the anonymous inner class. In addition to omitting the interface name and method name, the type of the parameter table is also omitted in the code. This is due to javac's type inference mechanism. The compiler can infer the parameter type based on contextual information. Of course, there are also times when the inference fails, in which case the parameter type needs to be specified manually. Note that Java is a strongly typed language, and each variable and object must have a clear type.
The basis for the abbreviation
Maybe you have already thought that the basis for using Lambda is that there must be a corresponding functional interface (a functional interface refers to an interface with only one abstract method inside). This is consistent with Java being a strongly typed language, which means that you cannot write Lambda expressions arbitrarily anywhere in the code. In fact, the type of Lambda is the type corresponding to the function interface. Another basis for lambda expressions is the type inference mechanism. If the context information is sufficient, the compiler can infer the type of the parameter table without explicitly naming it. Lambda expresses more legal written forms as follows:
// Written form of Lambda expression
Runnable run = () -> System.out.println("Hello World");// 1
ActionListener listener = event -> System.out.println("button clicked ");// 2
Runnable multiLine = () -> {// 3 code blocks
};
BinaryOperator<Long> add = (Long x, Long y) -> x + y;// 4
BinaryOperator<Long> addImplicit = (x, y) -> Inference
In the above code, 1 shows the abbreviation of the parameterless function; 2 shows the abbreviation of the parameterized function and the type inference mechanism; 3 is the writing method of the code block; 4 and 5 show the type inference mechanism again.
Custom function interface
Custom function interface is easy, you only need to write an interface with only one abstract method.
// Custom function interface
@FunctionalInterface
public interface ConsumerInterface<T>{
}
@FunctionalInterface in the above code is optional, but adding this annotation the compiler will help you check whether the interface complies with the functional interface specification. Just like adding the @Override annotation will check whether the function is overloaded.
With the above interface definition, you can write code similar to the following:
ConsumerInterface<String> consumer = str -> System.out.println(str);
Further, you can also use it like this:
class MyStream<T>{
}
MyStream<String> stream = new MyStream<String>();
stream.myForEach(str -> System.out.println(str));// Use custom function interface to write Lambda expression
What you can’t do is that Lambda itself is not an object.