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