Lambda表达式就是函数式思想
一、Lambda
1.体验Lambda表达式
public class Lambda {
    public static void main(String[] args) {
        //实现类的方式实现需求
        MyRunnable my = new MyRunnable();
        Thread t = new Thread(my);
        t.start();
        //匿名内部类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Lambda");
            }
        }).start();
        //Lambda表达式
        new Thread(() -> {
            System.out.println("Lambda");
        }).start();
    }
}
 
2.Lambda表达式的标准格式
():里面没有内容相当于方法的形式参数为空
 ->:用箭头指向后面要做的事情
 {}:包含一段代码,我们称之为代码块就是方法体中的内容
 ()->{}
3.Lambda表达式的练习
Lambda表达式的使用前提
 ·有一个接口
 ·接口中有且仅有一个抽象方法
特点
 ·Lambda表达式没有命名,用来像传递数据一样的传递操作
 ·函数接口里面只有一个抽象方法,被当作Lambda表达式的类型,最好使用@FunctionalInterface注解,防止其他人往里面添加方法
练习1:
	定义一个接口(Eatable),里面定义一个抽象方法:void eat()
	定义一个测试类(EatableDemo),在测试类中提供两个方法
		一个主方法
		一个UseEatable(Eatable e)
 
//接口
public interface Eatable {
    void eat();
}
//类
public class EatableDemo {
    public static void main(String[] args) {
        useEatable(()->{
            System.out.println("eat方法...");
        });
    }
    public  static void useEatable(Eatable e){
        e.eat();
    }
}
 
4.Lambda表达式的省略模式
参数的类型可以省略,有多个情况下,不能只省略一个
如果参数有且只有一个,那么小括号可以省略
如果代码块的语句只有一条,可以省略大括号和分号(如果有return,return 也要省略)
5.Lambda表达式的注意事项
使用Lambda,必须有上下文环境,才能推导出Lambda对应的接口
 ·局部变量赋值
 ·调用方法的参数
6.匿名内部类与Lambda表达式的区别
匿内部类
 ·接口、抽象类、具体类
 ·可以有多个方法
 ·会生成字节码文件
 Lambda
 ·接口
 ·接口中只能有一个方法
 ·动态生成,不会产生字节码文件
public class EatableDemo {
    public static void main(String[] args) {
        String []arr={
                "this","that","sear"
        };
        List<String> strings = Arrays.asList(arr);
        strings.forEach(p-> System.out.println(p));
        strings.forEach(System.out::println);
    }
}
 
二、函数式接口
1.什么是函数式接口
只包含一个抽象方法的接口,称为函数式接口。
可以通过Lambda表达式创建该接口的对象
可以在一个接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口。同时Javadoc也会包含一条声明,说明这个接口是函数式接口
2.Java内置四大核心函数式接口
| 函数式接口 | 参数类型 | 返回类型 | 用途 | 
|---|---|---|---|
| Consumer 消费型接口 | T | void | 对类型为T的对象应用操作,包含方法void accept(T t) | 
| Supplier 供给型接口 | 无 | T | 返回类型为T的对象,包含方法 T get() | 
| Function<T,R>函数性接口 | T | R | 对类型为T的对象应用操作并返回R类型结果,包含方法 R apply(T t) | 
| Predicate 断定型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean值。包含方法boolean test(T t) | 
三、方法引用
1.什么是方法引用
当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用
方法引用可以看作是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖
2.方法引用的使用
要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
格式:使用操作符 ” :: “将类(或对象)与方法名分隔开
如下三种主要使用情况:
对象 :: 实例方法名
类 :: 静态方法名
类 :: 实例方法名








