Simple use of lambda expressions

content

What is a lambda expression?

 Here's a simple case:

Simplified lambda expression:

Summarize:

Syntax format 1: no parameter, no return value

Syntax format 2: : Lambda requires a parameter, but no return value

Syntax format three: data type can be omitted

Syntax Format 4: : If Lambda only needs one parameter, the parentheses of the parameter can be omitted

Syntax format five: : Lambda requires two or more parameters, multiple execution statements, and can have a return value

Syntax Format 6: When there is only one Lambda body, if there is a statement, the return sign and curly brackets can be omitted.

Then let's talk about the functional interface:

Simply use lambda expressions to use four functional interfaces:

 Method references and constructor references


What is a lambda expression?

Lambda is an anonymous function, we can understand a Lambda expression as a piece of code that can be passed (pass the code like data).

Use it to write cleaner and more flexible code. As a more compact code style, the language expression ability of Java has been improved

Lambda expressions: A new syntax element and operator introduced in the Java 8 language. This operator is "->", and this operator is called a lambda operator or arrow operator.

It divides Lambda into two parts: Left: specifies the parameter list required by the Lambda expression: Right: specifies the Lambda body, which is the implementation logic of the abstract method, that is, the function to be executed by the Lambda expression

 Here's a simple case:

package com.chen.lambda;


/*
* 推导lambda表达式
* */
public class TestLambda {

    //3.静态内部类
   static class Like2 implements ILike{
        @Override
        public void lambda() {
            System.out.println("I like lambda2");
        }
    }

    public static void main(String[] args) {
        ILike like=new Like();
        like.lambda();

        like=new Like2();
        like.lambda();


        //4.局部内部类
        class Like3 implements ILike{
            @Override
            public void lambda() {
                System.out.println("I like lambda3");
            }
        }

        like=new Like3();
        like.lambda();


        //5.匿名内部类,没有类的名称,必须帮助接口或者父类
        like =new ILike() {
            @Override
            public void lambda() {
                System.out.println("I like lambda4");
            }
        };
        like.lambda();


        //6.用lambda简化
        like=()->{
            System.out.println("I like lambda5");
        };
        like.lambda();

    }



}

//1.定义一个函数式接口
interface ILike{

    void lambda();

}
//2.实现类
class Like implements ILike{
    @Override
    public void lambda() {
        System.out.println("I like lambda");
    }
}

Simplified lambda expression:

package com.chen.lambda;

public class TestLambda2 {

    static class Love implements ILove{

        @Override
        public void love(int a) {
            System.out.println("I Love you -->"+a);
        }
    }

    public static void main(String[] args) {
        ILove love=new Love();
        love.love(2);

        //匿名内部类
        ILove love2=new ILove() {
            @Override
            public void love(int a) {
                System.out.println("I Love you -->"+a);
            }
        };
        love2.love(5);


        //lambda表达式简化
        ILove love3=(int a)->{
            System.out.println("I Love you -->"+a);
        };
        love3.love(520);

        //简化1.参数类型
        ILove love4=(a)->{
            System.out.println("I Love you -->"+a);
        };
        love4.love(520);

        //简化2.简化括号
        ILove love5=a ->{
            System.out.println("I Love you -->" + a);
        };
        love5.love(520);

        //简化3.去掉花括号
        ILove love6=a ->
            System.out.println("I Love you -->" + a);
        love6.love(520);

        //总结:
          //lambda表达式只能有一行代码的情况下才能称为一行,如果有多行,那么就用代码块包裹
          //前提是接口为函数式接口
          //多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号

        ILove2 love7=(a,b) ->
               a*b;
      System.out.println(love7.love(7,8));
    }

}


interface ILove{
    void love(int a);

}
interface ILove2{
   int love(int a,int b);

}

class Love implements ILove{

    @Override
    public void love(int a) {
        System.out.println("I Love You");
    }
}

Summarize:

Syntax format 1: no parameter, no return value

  Runnable runnable1=()->System.out.println("ddd");

Syntax format 2: : Lambda requires a parameter, but no return value

Consumer<String> con=(String str) -> {System.out.println(str);};

//输出
   con.accept("aaa");

Syntax format three: data type can be omitted

​Consumer<String> con=(str) -> {System.out.println(str);};

Syntax Format 4: : If Lambda only needs one parameter, the parentheses of the parameter can be omitted

Consumer<String> con=str -> {System.out.println(str);};

Syntax format five: : Lambda requires two or more parameters, multiple execution statements, and can have a return value

 Comparator<Integer> com=(x, y) -> {
            System.out.println("实现函数式接口方法");
            return Integer.compare(x,y);
        };
  //输出结果
      System.out.println(com.compare(11,10));

Syntax Format 6: When there is only one Lambda body, if there is a statement, the return sign and curly brackets can be omitted.

 Comparator<Integer> com=(x, y) -> Integer.compare(x,y);
     

The parameter types in the above lambda expressions are all inferred by the compiler. There is no need to specify the type in the lambda
expression, and the program can still be compiled because javac
infers the type of the parameter in the background according to the context of the program. The type of the lambda expression depends on the
context and is inferred by the compiler. This is called "type inference"

Then let's talk about the functional interface:

An interface that contains only one abstract method is called a functional interface.
1. You can create objects of this interface through Lambda expressions. (If the lambda expression throws a checked exception (ie: a non-runtime exception), then the exception needs to be declared on the abstract method of the target interface).
2. We can use the @FunctionalInterface annotation on an interface to check if it is a functional interface. The javadoc will also contain a declaration that the interface is a functional interface.

In Java8, it is different. In
Java 8, Lambda expressions are objects, not functions, and they must be attached to a special class of object types—functional interfaces.
Simply put, in Java 8, a lambda expression is an instance of a functional interface. This is the relationship between Lambda expressions and functional interfaces.

That is, as long as an object is an instance of a functional interface, then the object can be represented by a lambda expression

 So what used to be represented by anonymous implementation classes can now be written with Lambda expressions

 

Simply use lambda expressions to use four functional interfaces:

Code case:

//Consumer<T> 消费型接口:
    @Test
    public void test1(){
        happy(10000,(m) -> System.out.println("今天消费了:"+(m+m)));
    }

    public  void happy(double money, Consumer<Double> con){

        con.accept(money);
    }



    //Supplier 供给型接口:
    @Test
    public void test2(){
        List<Integer> numList=  getNumList(10,() ->(int)(Math.random()*100));
        for(Integer num:numList){
            System.out.println(num);
        }
    }
    //需求:产生指定个整数,并放入到集合中
    public List<Integer> getNumList(int num, Supplier<Integer> sup){
        List<Integer>  list=new ArrayList<>();

        for(int i=0;i<num;i++){
            Integer n=sup.get();
            list.add(n);
        }
        return list;
    }



    //Function<T ,R> 函数型接口
    @Test
    public void test3(){
     String newStr  =   strHandler("\t\t\t 我爱爱学习",(str) -> str.trim());
     System.out.println(newStr);

        String subStr = strHandler("\t\t\t 我爱爱学习",(str)-> str.substring(2,5));
        System.out.println(subStr);
    }

    //需求:用于处理字符串
    public String strHandler(String str, Function<String,String> fun){

        return fun.apply(str);

    }

   //Predicate<T> 断言型接口

    @Test
    public  void test4(){
        List<java.lang.String> list= Arrays.asList("hello","hello2","hello3");
         List<String> strList=filterStr(list,(s) -> s.length()>5);

         for(String str:strList){
             System.out.println(str);
         }
    }

    //需求:将满足条件的字符串,放入集合中
    public List<String> filterStr(List<String> list, Predicate<String> pre){

        List<String> strList=new ArrayList<>();

        for(String str:list){
            if(pre.test(str)){
                strList.add(str);
            }
        }
      return  strList;

    }

 Method references and constructor references

method reference

When an operation to be passed to the Lambda body already has an implemented method, a method reference can be used!
1. A method reference can be seen as a deep expression of a lambda expression. In other words, a method reference is a lambda expression, which is an instance of a functional interface, and it refers to a method through the method name
, which can be considered as a syntactic sugar for a lambda expression.
2. Requirements: The parameter list and return value type of the abstract method that implements the interface must be consistent with the parameter list and return value type of the method referenced by the method!

3. Format: Use the operator "::" to separate the class (or object) from the method name.
 There are three main use cases as follows:
 object::instance method name
 class::static method name
 class::instance method

E.g:

Consumer<String> con=(x) -> System.out.println(x);

//相当于

Consumer<String> con=System.out::println;
Comparator<Integer> c=(x,y) -> Integer.compare(x,y);

//相当于

Comparator<Integer> c2=Integer::compare;
BiPredicate<String,String> bp=(x,y) -> x.equals(y);

//相当于

BiPredicate<String,String> bp1=String::equals;
//输出结果
 System.out.println(bp1.test("s","t"));

Constructor reference

Format: ClassName::new
is combined with the functional interface and is automatically compatible with the methods in the functional interface.
A constructor reference can be assigned to a defined method, requiring the constructor parameter list to be
consistent with the parameter list of the abstract method in the interface! And the return value of the method is the object of the corresponding class of the constructor

Function<Integer,Myclass> fun=(n) -> new Myclass(n);

//相当于

Function<Integer,Myclass> fun=Myclass::new;

array reference

Function<Integer,Integer[]> fun3=(n) -> new Integer[n];

//相当于

Function<Integer,Integer[]> fun4=Integer[]::new;
   System.out.println(fun4.apply(1555).length);

Guess you like

Origin blog.csdn.net/qq_44716544/article/details/119047362