Lambda表达式

Posted chenyameng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lambda表达式相关的知识,希望对你有一定的参考价值。

#java8——Lambda表达式

1.简介:

jdk1.8中引入Lambda表达式,其作用是使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面这个例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。

eg:摘自百度百科:
没有使用Lambda的老方法:

button.addActionListener(new ActionListener()
    public void actionPerformed(ActionEvent actionEvent)
        System.out.println("Action detected");
    
);

使用lambda后:

button.addActionListener( actionEvent ->  
    System.out.println("Action detected");
);

Lambda表达式中,在Thread多线程的使用过程中较为频繁:如:
使用匿名内部类的时候重写run方法:

Runnable runnable1=new Runnable()
@Override
public void run()
    System.out.println("Running without Lambda");

;

使用Lambda后:

Runnable runnable2=()->System.out.println("Running from Lambda");

lambda表达式的标准格式:
  有三部分
  一些参数
   一个箭头
   一段代码
  格式:
       (参数列表)->一些重写方法的代码
       解释说明格式:
   ()接口中抽象方法的参数列表:没有参数空,有就写,多个用,分割
   ->传递的意思,把参数传递给方法体
   重写接口的抽象方法的方法体

2,函数式编程思想概述

2.1 区别:
面向对象的思想:    
    ·做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:
    ·只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程

3. 讲述

例如:在多线程中:创建一个实现类,用于实现RUnnable接口,重写了run方法

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

创建主类,用于实现
public class Demo1Runnable 
    public static void main(String[] args) 
        RunnableImpl runnable=new RunnableImpl();
        Thread t=new Thread(runnable);
        t.start();
        //简化代码,匿名内部类
       Runnable runnable1= new Runnable()

            @Override
            public void run() 
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            
        ;
        new Thread(runnable1).start();//调用线程的启动。

这是存在冗余的程序代码块,

简化一:
public class Demo1Runnable 
    public static void main(String[] args) 
        RunnableImpl runnable=new RunnableImpl();
        Thread t=new Thread(runnable);
        t.start();
        //简化代码,匿名内部类
       Runnable runnable1= new Runnable()

            @Override
            public void run() 
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            
        ;
       new Thread(runnable1).start();
       //继续简化
        new Thread(new Runnable()

            @Override
            public void run() 
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            
        ).start();
    


采用匿名内部类,实现线程。

总结:

简化该线程的方法:
1. 
     Runnable runnable1= new Runnable()

            @Override
            public void run() 
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            
        ;
       new Thread(runnable1).start();

2.  这段代码是1中的综合
     new Thread(new Runnable()

            @Override
            public void run() 
                System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
            
        ).start();
3. 使用lambda进行简化codes
    lambda表达式的标准格式:
*   有三部分
*   一些参数
*   一个箭头
*   一段代码
*  格式:
*       (参数列表)->一些重写方法的代码
*       解释说明格式:
*   ()接口中抽象方法的参数列表:没有参数空,有就写,多个用,分割
*   ->传递的意思,把参数传递给方法体
*   重写接口的抽象方法的方法体

codes:

    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();
        

    

案例二(无参无返回值):

给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:

public interface Cook 
    public abstract void makeFood();

在下面的代码中,请使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”字样:
技术图片
解答:

    public class Demo1Cook 
    public static void main(String[] args) 
        invokeCook(new Cook() 
            @Override
            public void makeFood() 
                System.out.println("吃放了");
            
        );
       // 使用lambda表达式
        invokeCook(()->
            System.out.println("吃饭了");
        );
        //省略lambda
        invokeCook(()->System.out.println("吃饭了"));
    
    //定义方法,参数传递cook接口,方法内部调用cook接口中的方法makeFood
    public static void invokeCook(Cook cook)
        cook.makeFood();
    

    

案例三(参数和返回值):

需求:
使用数组存储多个Person对象
对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
1.创建Person类

package com.lambdaDemo;
public class Person 
    private String name;
    private int age;

    public Person() 
    

    public Person(String name, int age) 
        this.name = name;
        this.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;
    

    @Override
    public String toString() 
        return "Person" +
                "name='" + name + '\\'' +
                ", age=" + age +
                '';
    

传统的排序:

import java.util.Arrays;
import java.util.Comparator;
public class Demo06Comparator 
public static void main(String[] args) 
    // 本来年龄乱序的对象数组
    Person[] array = 
    new Person("古力娜扎", 19),
    new Person("迪丽热巴", 18),
    new Person("马尔扎哈", 20) ;
    // 匿名内部类
        Comparator<Person> comp = new Comparator<Person>(
                @Override
                public int compare(Person o1, Person o2) 
                return o1.getAge() ‐ o2.getAge();
            
        ;
        Arrays.sort(array, comp); // 第二个参数为排序规则,即   Comparator接口实例
        for (Person person : array) 
            System.out.println(person);
        
    

知识点:创建对象数组:

对象名[] 数组名称=new 对象名(),new 对象名(),new 对象名(),  

排序:
使用Comparator

Comparator<Person> comp = new Comparator<Person>(
                @Override
                public int compare(Person o1, Person o2) 
                return o1.getAge() ‐ o2.getAge();
            
        ;
升序是参数1-参数2,降序是参数2-参数1.
记得使用Arrays.sort(array, comp);进行排序,然后遍历数组即可

使用Lambda的排序:

public class Demo1Arrays 
    public static void main(String[] args) 
        Person[] arr=
                new Person("cym",11),
                new Person("yyh",221),
                new Person("jhj",13),
        ;
        Arrays.sort(arr, new Comparator<Person>() 
            @Override
            public int compare(Person o1, Person o2) 
                return o1.getAge()-o2.getAge();
            
        );
        for (Person p : arr) 
            System.out.println(p);
        
        //使用lambda表达式简化匿名内部类
        System.out.println("------------使用lambda表达式");
        Arrays.sort(arr,(Person o1,Person o2)->
            return o2.getAge()-o1.getAge();

        );
        Arrays.sort(arr,(o1,o2)->o2.getAge()-o1.getAge());
        for (Person p : arr) 
            System.out.println(p);
        
    

技术图片

案例三:有参有返回

public interface Calculate 
    //定义两个int和方法
    public abstract int calc(int a,int b);

使用lambda

package com.lambdaDemo1;


public class Demo1Calculator 
    public static void main(String[] args) 
        //调用invakeCalc方法,参数是接口,可以使用匿名内部类

        invokeCalc(10, 20, new Calculate() 
            @Override
            public int calc(int a, int b) 
                return  a+b;
            
        );
        //使用lambda表达式简化匿名内部类的书写
       invokeCalc(10,20,(int a,int b)->
           return a+b;
       );



       //省略
        invokeCalc(10,20,(a,b)-> a+b);
    
    //定义一个方法,参数传递两个int类型的整数,参数cdCalculator接口,
    // 方法内部电泳Calculator中的方法calc计算和
    public static void invokeCalc(int a,int b ,Calculate calculate)
        int sum= calculate.calc(a,b);
        System.out.println(sum);
    

Lambda的省略《规则》:

/*可推到可省略
* 凡是根据上下文推到出来的内容,都可以省略书写
* 可以省略的内容:
*   1,(参数列表):括号中参数列表的数据类型,可以省略不写
*   2,(参数列表):括号中的参数如果只有一个,那么类型和()都可以省略
*   3.代码ruguo 的代码只有一行,无论是否有返回值,都可以省略return 和分号
*   ·要省略都一起省略

1.  省略前:
    new Thread(()-> 
            System.out.println(Thread.currentThread().getName()+"新的线程创建了---");
        
    ) .start();
    省略后:
    new Thread(()->System.out.println(Thread.currentThread().getName()+"新的线程创建了---")
    ) .start();
explanation:如果代码块中只有一行代码,则可以省去,和;
2. 省略前:
     invokeCook(()->
        System.out.println("吃饭了");
    );
    省略后:
    invokeCook(()->System.out.println("吃饭了"));
    explanation:省略了和; 因为代码块就一句;
3. 省略前:
     Arrays.sort(arr,(Person o1,Person o2)->
        return o2.getAge()-o1.getAge(););
    省略后:
    Arrays.sort(arr,(o1,o2)->o2.getAge()-o1.getAge());
    explanation:变量名一样可以省略,代码块就一句话,可以省略return和 ;
4.  省略前:
    invokeCalc(10,20,(int a,int b)->
       return a+b;
   );
    省略后:
    invokeCalc(10,20,(a,b)-> a+b);
    explanation:同上

github-----》》》"lambda"

以上是关于Lambda表达式的主要内容,如果未能解决你的问题,请参考以下文章

表达式 lambda 和语句 lambda 的区别

Lambda简介

Lambda 表达式的演示样例-来源(MSDN)

线程池Lambda表达式

:Java之lambda表达式

JDK8新特性之Lambda表达式