Enjoy learning class guest author: Lao Gu
Reprint please state the source!
preface
The syntax of lambda expressions was introduced in the previous article and continues today
Lambda type
Lambda expressions can be thought of as objects. The type of a Lambda expression is called the target type. The target type of a Lambda expression is functional Interface.
There is an interface that is a function interface if there is only one explicitly declared abstract method. It is usually marked with @functionalInterface (or not). For example, the following
We saw that the last Comparator interface declared two methods that didn’t seem to meet the definition of a function interface. But the Comparator was a function interface. This is because the equals method is Object, and all interfaces declare the Object public method (though mostly implicitly). So, the Comparator explicitly declares equals without affecting it as a function interface. Although Lambda can be treated as an Object, it requires an explicit conversion. We can assign a function to a Lambda expression:
Runnable r1 = () -> {System.out.println("Hello Lambda!"); };Copy the code
Then assign to an Object:
Object obj = r1;
Copy the code
But you can’t do this:
Object obj = () -> {System.out.println("Hello Lambda!"); }; // ERROR! Object is not a functional interface!Copy the code
It must be explicitly converted to a function interface:
Object o = (Runnable) () -> { System.out.println("Hello Lambda!"); };
Copy the code
A Lambda expression can only be used as an Object if it is transformed into a function interface. So the following will not compile:
System.out.println( () -> {} ); / / error! Target type unknownCopy the code
Must transform first:
System.out.println( (Runnable)() -> {} ); / / rightCopy the code
We can define a no-argument, no-return interface, like Runnable
@FunctionalInterface
public interface MyRunnable {
public void run();
}
Copy the code
So all of the following is correct
Runnable r1 = () -> {System.out.println("Hello Lambda!"); }; MyRunnable r2 = () -> {System.out.println("Hello Lambda!"); };Copy the code
This shows that a Lambda expression can have multiple target types (function interfaces), as long as the function matches. Note, however, that a Lambda expression must have at least one target type.
Lambda fields and access restrictions
A field is a scope, and the arguments in the argument list of a Lambda expression are valid within the scope of that Lambda expression (the field). Inside a Lambda expression, you can access external variables: local variables, class variables, and static variables, with varying degrees of restriction.
1. Access local variables
Local variables outside of a Lambda expression are implicitly compiled by the JVM to final and therefore can only be accessed without modification.
2. Access static and member variables
Inside Lambda expressions, static and member variables are readable and writable.
Built-in functional interfaces
If you use a Lambda expression, you need to write an interface definition of your own. In fact, many interfaces are just the input type and return value is different, so Java provides us with several common standard function interfaces:
Void accept(T T); Supplier< T >sup supply interface: T get(); Function< T, R >fun: R apply (T T); Predicate< T > : Predicate interface: Boolean test(T T);
1. Consumer interface
The method on the interface is void Accept (T T), which has one parameter and no return value. The caller passes in the value without returning it, figuratively as a consumer
This is the processing (consumption) of the passed num parameter value. In the end to process, specific in
(num) -> System.out.println("Consumed" + num)
Copy the code
In the above code, is a typical 1 argument, no return value consumption; If there is no built-in function interface, then we need to define one of our own, such as:
interface MyConsumer<T>{
void doFunction(T t);
}
Copy the code
We find that there is no difference between the built-in function interface, except that the interface name and method name are different. In fact, the essence is the same, which is why Java provides some built-in functions, which can reduce a lot of code.
2. Supplier interface
Interface method T get(), no arguments, return value; You don’t need to give parameters to the other side, but always return to the other side, defined as a supply interface
The above code returns a new entity object.
3, Function interface
The method R apply (T T) in the interface has parameters and returns values;It’s a typical functionFunctional interface
The interface implementation converts to uppercase characters.
4, Predicate type interfaces
Boolean test(T T) ¶ Boolean test(T T) is a conditional checking method
Built-in function interface, greatly improve the efficiency of development, reduce the development code
Method references
A method reference is a simplified version of a Lambda expression with the syntax:
ObjectRef::methodName
The left side can be the class name or instance name, with the method reference symbol “::” in the middle, and the corresponding method name on the right. Method references can be divided into three categories.
Prerequisites: The argument list and return value types of the calling method in the Lambda body should be the same as those of the abstract method in the functional interface
Static method reference
Let’s do one more example
In the code above, we see that the Converter anonymous class overload method calls the static method String2Int of ReferenceTest. The method parameter type and return value type of the function interface are the same as String2Int, the input parameter is String, and the return value is Integer. So we can simplify this to
It’s pretty neat to just do it statically.
Instance method reference
If the implementation of a functional interface happens to be implemented by calling an instance method of an instance, then instance method references can be used
Object method reference
The first parameter type of the abstract method happens to be the type of the instance method (abstract methods of functional interfaces must have input parameters). The remaining parameters of the abstract method can be used as the parameters of the instance method.
If the implementation of a functional interface can be implemented by instance method calls described above, then references to object methods can be used **(both conditions must be met)**
We see that the first argument, Prod s, is of the same type as the instance object new Prod; The remaining arguments, s1, happen to be arguments to the instance method fun; This simplifies to Prod::fun
Constructor reference
If the implementation of a functional interface happens to be implemented by calling a constructor of a class, then constructor references can be used, syntax [class name ::new]
Above are the no-argument constructors. Now look at the parameterized constructors
Here, Lao Gu comes to a method reference summary:
conclusion
Lambda expressions to master, is to partners often to write, to be able to use freely, although the code is relatively simple, but really no contact with the developer looks like, muddled, not strong readability. There is a Stream of knowledge. Thank you!!
Follow me and share more technical dry goods