2019-01-27

Lambda表达式

函数式编程思想

在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿什么东西做什么事情”。

  • 相对而言,面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做。
  • 面向对象的思想:
    做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
  • 函数式编程思想:
    只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程.
冗余的Runnable代码
public class lambdaDemo {
    public static void main(String[] args) {
        // 匿名内部类  传统写法
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("多线程任务执行");
            }
        };
        new Thread(runnable).start();
        //使用lambda表达式方法
        Runnable runnable1 = () -> {
        };
        new Thread(runnable1).start();
        
        //使用方法优化
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("多线程执行");     
            }
        });
        
        //lambda优化写法  使用匿名类部类    并不需要中间的Runnable对象,而是直接得出结果-->函数式编程思想
        new Thread(()->System.out.println("多线程任务执行")).start();
    }
}
使用实现类

要启动一个线程,需要创建一个 Thread 类的对象并调用 start 方法。而为了指定线程执行的内容,需要调用 Thread 类的构造方法:

package lambda_de;

/**
 * @author lx
 * @date 2019/1/27 - 16:45
 */
class Lambda_demo2 implements Runnable{
    @Override
    public void run() {
        System.out.println("多线程任务执行");
    }
}
public class Test{
    public static void main(String[] args) {

        Lambda_demo2 demo2 = new Lambda_demo2();

        new Thread(demo2).start();
    }
}
匿名内部类的好处与弊端

一方面,匿名内部类可以帮我们省去实现类的定义;另一方面,匿名内部类的语法稍微复杂一点.
仔细分析该代码中的语义, Runnable 接口只有一个 run 方法的定义:

  • public abstract void run();
    即制定了一种做事情的方案(其实就是一个函数):

  • 无参数:不需要任何条件即可执行该方案。

  • 无返回值:该方案不产生任何结果。

  • 代码块(方法体):该方案的具体执行步骤。

同样的语义体现在 Lambda 语法中,要更加简单

() -> System.out.println("多线程任务执行!")

  • 前面的一对小括号即 run 方法的参数(无),代表不需要任何条件;
  • 中间的一个箭头代表将前面的参数传递给后面的代码;
  • 后面的输出语句即业务逻辑代码;
Lambda标准格式

(参数类型 参数名称) -> { 代码语句 }

  • 小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
  • -> 是新引入的语法格式,代表指向动作。
  • 大括号内的语法与传统方法体要求基本一致

使用Lambda标准格式(无参无返回)

//创建cook厨子接口,内含唯一的抽象方法makeFood,无参数无返回值.
public interface Cook {  
  void makeFood();
 }
//创建测试类
public class Demo05InvokeCook {    
public static void main(String[] args) {      
  // TODO 请在此使用Lambda【标准格式】调用invokeCook方法    }
    private static void invokeCook(Cook cook) {   
     cook.makeFood(); 
   }
 }
//使用lambda表达式
public static void main(String[] args) {  
  invokeCook(() -> {       
 System.out.println("吃饭啦!"); 
   });
 }

lambda有参数和返回值

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

package lambda_de;

/**
 * @author lx
 * @date 2019/2/26 - 15:55
 */
public class Person implements Comparable{
    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;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
//比较对象属性大小时方法二,比较对象实现comparable接口,并重写compareTo方法
    @Override
    public int compareTo(Object o) {
            int result=0;
            Person person;
        if (o != null) {
            person =(Person)o;
            return person.getAge()-age;
        }

        return result;
    }
}
package lambda_de;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author lx
 * @date 2019/2/26 - 16:04
 */
public class Compare_demo{
    public static void main(String [] args){
        Person[]  p ={
                new Person("陈奕迅",29),
                new Person("林志颖",35),
                new Person("吴亦凡",32),
        };
        //(参数1,参数2) - > 函数的运算
        Comparator<Person> comparator= (o1, o2) -> o1.getAge()-o2.getAge();
        //排序
     Arrays.sort(p,comparator);

        for (Person ps:p
             ) {
            System.out.println(ps);
        }

    }
}
Lambda的使用前提
    1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。
      无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一 时,才可以使用Lambda。
    1. 使用Lambda必须具有上下文推断。 也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 写在开头:本人打算开始写一个Kotlin系列的教程,一是使自己记忆和理解的更加深刻,二是可以分享给同样想学习Kot...
    胡奚冰阅读 5,129评论 0 6
  • 原文链接:https://github.com/EasyKotlin 值就是函数,函数就是值。所有函数都消费函数,...
    JackChen1024阅读 11,349评论 1 17
  • promise 涵义 Promise是异步编程的一种解决方案,ES6原生提供了Promise对象从语法上说是一个对...
    瑶九九阅读 3,294评论 0 0
  • 生日啦,又过了一年,长大了一岁…… 活了二十几岁,也该有点感悟 人生精彩 分享至上 …… 当你觉得多努力就多成功的...
    流浪的壮汉阅读 1,477评论 0 4
  • 佛陀教导我们“自律”万般重要,自律是一切善行的灵魂。自律犹如如意宝一般给予一切,自律是梦想的支柱,未来的福田,修行...
    曲吉旺旭阅读 2,507评论 0 1

友情链接更多精彩内容