Function (Lambda) expression learning

introduction

When writing multi-threaded code, we often have to create some anonymous inner classes in order to realize multi-threaded programs, but creating anonymous inner classes is not the purpose. Our purpose is to realize multi-threaded programs rather than to realize anonymous inner classes, so in In this process, creating anonymous inner classes is a little redundant.

Lambda's ideas and cases

Lambda expression thought

Lambda expressions are result-oriented, which is also in line with "the basic idea of ​​the boss." The boss only cares about what you do, but never cares about what you do and how much effort you put in. The essence of lambda expression is related to "Boss" has the same thinking.
When we go to create a multi-threaded program, we have to create some classes, these classes seem so redundant. The sample code is as follows.
RunnableImpl class code:

public class RunnableImpl implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" 新线程创建了");
    }
}

Test class

public class Demo01Runnable {
    public static void main(String[] args) {
        //创建Runnable接口的实现类对象
        RunnableImpl run = new RunnableImpl();
        //创建Thread类对象,构造方法中传递Runnable接口的实现类
        Thread t = new Thread(run);
        //调用start方法开启新线程,执行run方法
        t.start();
        //简化代码,使用匿名内部类,实现多线程程序
        Runnable r = new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" 新线程创建了");
            }
        };
        new Thread(r).start();
        //简化代码
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" 新线程创建了");
            }
        }).start();
    }
}

Code running results
Insert picture description here
can be seen from the above case, in the process of creating a Runnable multi-threaded program, you have to new Thread object and RunnableImpl object, in order to solve the problem of code redundancy, Lambda expression boarded the prehistoric jdk The stage is up, and the following focuses on how Lambda expressions solve code redundancy.

How to use lambda expressions

Case number one

This summary focuses on the implementation of lambda expressions for multi-threaded programs, first on the code

public class Demo02Lambda {
    public static void main(String[] args) {
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+" 新线程创建了");
            }
        }).start();

        //使用Lambda表达式,实现多线程
        new Thread(()->{
                System.out.println(Thread.currentThread().getName()+" 新线程创建了");
            }
        ).start();
        //优化省略Lambda
        new Thread(()->System.out.println(Thread.currentThread().getName()+" 新线程创建了")).start();
    }
}

The biggest difference between the two methods is that through Lambda expression we can omit the creation of RunnableImpl objects, Lambda expressions can directly call the run method in the Runnable interface

Case two

When there are parameters in the method we need to call, the lambda expression can also be solved for me. Let’s discuss the case. The requirement of the case is to store personal information in an array, and then sort it by age. The code is submitted.
person class

public class Person {
    private String name;
    private int age;
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

Test class

public class DemoTest {
    public static void main(String[] args) {
        System.out.println("请输入人数: ");
        Scanner sc = new Scanner(System.in);
        String next = sc.nextLine();
        int arraysIndex = Integer.parseInt(next);
        Person01[] person01s = new Person01 [arraysIndex];
        System.out.println("总共创建了"+person01s.length+"个人的模板");
        System.out.println("-------------------------------");
        System.out.println("请输入您要输入的人物信息--->"+"格式信息::"+"-> 赵丽颖,31");
        //安装
        for (int i = 0; i < person01s.length; i++) {
            System.out.println("正在输入第"+(i+1)+"个人的信息");
            String s = sc.nextLine();
            String[] split = s.split(",");
            person01s[i] = new Person01();
            person01s[i].setName(split[0]);
            person01s[i].setAge(Integer.parseInt(split[1]));
        }
        //采用普通方式
        /*Arrays.sort(person01s, new Comparator<Person01>() {
            @Override
            public int compare(Person01 o1, Person01 o2) {
                return o1.getAge()-o2.getAge();
            }
        });*/
        //采用lambda表达式
        /*Arrays.sort(person01s,(Person01 o1,Person01 o2)->{
            return  o1.getAge()-o2.getAge();
        });*/
        Arrays.sort(person01s,(o1,o2)->o1.getAge()-o2.getAge());
        System.out.println("-------------------------");
        for (int i = 0; i < person01s.length; i++) {
            System.out.println(person01s[i].getName()+"-->"+person01s[i].getAge());
        }

    }
}

Test results
Insert picture description here
Test results show that using lambda perfectly solves the sorting problem.

Case three

In the first two cases, jdk's own interface is mainly used to implement lambda expressions, such as Runnable and Comparator interfaces. In case three, Xiao Yuan will use a custom interface to implement the process of using functions directly in lambda expressions.
Implement a simple addition calculation process in the case

Addition interface

public interface Multiplication {
    public abstract  Double mul(Double a, Double b);
}

Test class

public class Demo02Mul {
    public static void main(String[] args) {
        System.out.println("请输入两个相乘的数:");
        System.out.println("请输入第一个数;");
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        double a = Double.parseDouble(s);
        System.out.println("请输入第二个数;");
        s=sc.nextLine();
        double b = Double.parseDouble(s);
        System.out.println("计算结果是:");
        /*muli(a, b, new Multiplication() {
            @Override
            public Double mul(Double a, Double b) {
                return a*b;
            }
        });*/
        /*muli(a,b,(Double aa, Double bb)->{
            return aa*bb;
        });*/
        muli(a,b,(aa,bb) ->  aa*bb);
    }

    private static void muli(Double a,Double b,Multiplication m){
        Double mul = m.mul(a,b);
        System.out.println(mul);
    }
}

Insert picture description here

to sum up

From the above three cases, we can summarize the necessary prerequisites for using lambda expressions.
1. There is a sufficient interface. There is one and only one abstract method in the interface (abstract method uniqueness). Too many abstract methods cause lambda to fail to resolve the correspondence. The function.
2. The use of Lambda must have context inference (the parameters of the method must correspond to the lambda).
In the same way, we can also know the simplification rules of lambda expressions:
1. The type of the parameter in the parentheses can be omitted;
2. If there is one and only one statement in the braces, regardless of whether there is a return value, you can omit the big Brackets, return keyword, and statement semicolon.

Guess you like

Origin blog.csdn.net/xueshanfeitian/article/details/106812234