Java8之lambda表达式略解

一、什么是lambda表达式?

Lambda 表达式,其实就是匿名函数。而函数其实就是功能(function),匿名函数,就是匿名的功能代码了,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使 Java的语言表达能力得到了提升。Lambda就是为了替换匿名函数而存在的【本人的理解】;

二、lambda的使用场景。

Lambda表达式是用于替代匿名函数,写出更简洁的代码的,因此,所有期待匿名函数、或者函数式接口类型参数出现的地方都可以使用Lambda替换。

三、什么是函数式接口。

函数式接口:Functional Interface. 
定义的一个接口,接口里面必须 有且只有一个抽象方法 ,这样的接口就成为函数式接口。 
在可以使用lambda表达式的地方,方法声明时必须包含一个函数式的接口,匿名内部类其实是函数式接口的实现类。 
(JAVA8的接口可以有多个default方法)

四、写法、规则

基本语法: 
(parameters) -> expression 或 (parameters) ->{ statements; } 
即: 参数 -> 带返回值的表达式/无返回值的陈述


----------


//1. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y;

//2. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s);


----------
lambda表达式的结构

参数可以是零个或多个
参数类型可指定,可省略(根据表达式上下文推断)
参数包含在圆括号中,用逗号分隔
表达式主体可以是零条或多条语句,包含在花括号中
表达式主体只有一条语句时,花括号可省略
表达式主体有一条以上语句时,表达式的返回类型与代码块的返回类型一致
表达式只有一条语句时,表达式的返回类型与该语句的返回类型一致
//零个
 ()-> System.out.println("no argument");

//一个
  x->x+1

//两个
  (x,y)->x+y

//省略参数类型
 View.OnClickListener oneArgument = view->Log.d(TAG,"one argument");
 //指定参数类型
 View.OnClickListener oneArgument = (View view)->Log.d(TAG,"one argument");

//多行语句
//返回类型是代码块返回的void
View.OnClickListener multiLine = (View view)->{
      Log.d(TAG,"multi statements");
      Log.d(TAG,"second line");
}

//返回类型是表达式主体语句的返回类型int
(int x)->x+1

五.几个特性

1. 类型推导 
编译器负责推导lambda表达式的类型。它利用lambda表达式所在上下文所期待的类型进行推导, 
这个被期待的类型被称为目标类型。就是说我们传入的参数可以无需写类型了!

六、demo
1.使用lambda表达式实现Runnable

package com.lz.test;
/**
 * 使用lambda表达式替换Runnable匿名内部类
 * @author MingChenchen
 *
 */
public class RunableTest {
    /**
     * 普通的Runnable
     */
    public static void runSomeThing(){
        //new Runnable()实际上实现的接口的匿名子类;
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                System.out.println("I am running");
            }
        };
        new Thread(runnable).start();
    }

    /**
     * 使用lambda后的
     */
    public static void runSomeThingByLambda(){
        //此处期待的是一个函数式类型的参数,因此可以使用lambda表达式进行替换;
        new Thread(() -> System.out.println("I am running")).start();
    }

    public static void main(String[] args) {
        //runSomeThing();
     runSomeThingByLambda();
    }
}

上述代码中:
() -> System.out.println(“I am running”)就是一个lambda表达式,
可以看出,它是替代了new Runnable(){}这个匿名内部类。

2.使用lambda表达式实现Comparator

Students.java


----------


package com.lz.test;

/**
 * Lambda表达式测试实体;
 * @author JunZhou
 * @Time 2018年1月29日下午10:44:56
 */
public class Students {
    private int age;
    private int score;

    public Students(int age, int score) {
        super();
        this.age = age;
        this.score = score;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

package com.lz.test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class LambdaTestDemo {
    public static void main(String[] args) {
        List<Students> students = new ArrayList<Students>();
        students.add(new Students(23, 100));
        students.add(new Students(27, 98));
        students.add(new Students(29, 99));
        students.add(new Students(29, 98));
        students.add(new Students(22, 89));
        // 未使用lambda表达式之前的代码;
        /*
         * Collections.sort(students, new Comparator<Students>() {
         * 
         * @Override public int compare(Students o1, Students o2) { int i =
         * o1.getScore() - o2.getScore(); if(i == 0){ return o1.getAge() -
         * o2.getAge(); } return i; } });
         */

        // 使用lambda表达式替换之后的代码;
        Collections.sort(students, (Students o1, Students o2) -> {
            int i = o1.getScore() - o2.getScore();
            if (i == 0) {
                return o1.getAge() - o2.getAge();
            }
            return i;
        });
        for (Students stu : students) {
            System.out.println("score:" + stu.getScore() + ":age" + stu.getAge());
        }
    }
}

7、参考文章
JAVA8之lambda表达式详解,及stream中的lambda使用

30 分钟入门 Java8 之 lambda 表达式


Reprint please specify: Blog4Jun Java8之lambda表达式略解

Previous
Javascript节流和防抖 Javascript节流和防抖
在前端开发中可能会遇到一些频发触发的事件,例如window 的 resize(浏览器窗口或者HTML对象改变大小)、scroll(滚动条事件)mousedown(鼠标在元素上按下事执行事件)、onmousemove(鼠标指针移动到元素上触发
2018-12-04 Pursue
Next
Java 对象的存储区域 Java 对象的存储区域
程序运行时,我们最好对数据保存到什么地方做到心中有数。特别要注意的是内存的分配。有六个地方都可以保存数据: 转载自:Java 对象的存储区域 (1)寄存器; 这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处
2018-12-04 Pursue