Analysis of Java8's lamda expression 02

"Analysis of Java8's lamda expression 02"

 

In "Analysis of lamda expressions in Java 8 01", I believe that everyone has a certain understanding of lamda expressions and a clear basic syntax and usage. So in the next chapter, we will continue to understand and learn lamda expressions.

 

Take a look at an example from the previous chapter:

Runnable t1 = () -> System.out.println(Thread.currentThread().getId());

 

In the above program example, the instance of the Runnable interface is generated by the lamda expression, so let's think about it, how does the compiler achieve automatic type inference at compile time? That is, how does the compiler know the target type corresponding to the lamda expression. I don't know if you still remember that functional interfaces only allow the definition of one abstract interface (function descriptor), so when the above code is compiled, the compiler will automatically infer what the target type is based on the context of lamda.

 

And in addition to explicitly declaring the parameter type in the parameter list of lamda, the compiler can still automatically infer the type, as shown below:

@FunctionalInterface
public interface Compare {
 public boolean compare(String str1, String str2);
}
/* automatic type inference */
Compare compare = (str1, str2) -> str1.equals(str2);
compare.compare("a", "b");

 

In fact, in the final analysis, the compiler implements automatic type inference by matching the method signature and the lamda expression signature when compiling .

 

In addition to the parameters in the parameter list, the body of the lamda expression can also use local variables. Of course, everyone needs to pay attention here that the local variables must be final. Of course, in Java8, there is no need to explicitly define the anonymous class in the outer scope. The variable is explicitly declared final, but in fact the local variable is still final, it's just implicit:

/* Implicitly defined fina constants */
String str = "id:";
/* lamda usage */
new Thread(() -> {
 System.out.println(str + Thread.currentThread().getId());
}).start();

 

 Next, let's take a look at how to use method references to simplify lamda expressions, yes, more concise operations, why not. Simply put, a method reference can be thought of as a shorthand for a lamda expression that just calls a specific method . If a lamda stands for "call this method directly", then there is no need to describe how to call it, but to call it by name:

List<String> list = Arrays.asList("a", "b", "c");
/* Iterate using lamda expressions */
list.forEach((str) -> System.out.println(str));
/* Use method references to iterate */
list.forEach(System.out::println);
/* Use lamda expression to get string length */
Consumer<String> com = (str) -> str.length();
/* Use method reference to get string length */
com = String::length;

 

 Similar to method references, for constructors, we can create an object reference using the type name and the keyword new ( className::new ):

public class Main {
 public static void main(String[] args) {
  /* use lamda expressions */
  Function<String, Integer> function = (str) -> new Integer(str);
  function.apply("123");
  /* use lamda expressions */
  function = Integer::new;
  function.apply("321");
  /* use lamda expressions */
  FunctionaTest<String, String, String, Test> fTest = (str1, str2, str3) -> new Test(str1, str2, str3);
  fTest.get("a", "b", "c");
  /* use lamda expressions */
  fTest = Test::new;
  fTest.get("d", "e", "f");
 }
}
/* Constructor with multiple parameters */
class Test<T, U, V> {
 Test(T t, U u, V v) {
 }
}
@FunctionalInterface
interface FunctionaTest<T, U, V, R> {
 public R get(T t, U u, V v);
}

 

In the above program example, the author demonstrates how to create object references through constructor references. Here you need to pay attention that if the constructor has parameters, no matter how many parameters there are, the syntax of the constructor reference is always className::new , then the signature of the constructor reference must match the method signature of the functional interface .

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326560633&siteId=291194637