我们都知道在Java8中引入了许多新特性,Lambda表达式,下面就Lambda表达式给大家介绍一下。

一、什么是Lambda表达式?

从java8出现以来lambda是最重要的特性之一,它可以让我们用简洁流畅的代码完成一个功能。 很长一段时间java被吐槽是冗余和缺乏函数式编程能力的语言,随着函数式编程的流行java8种也引入了 这种编程风格,lambda表达式是一段可以传递的代码,它的核心思想是将面向对象中的传递数据变成传递行为。

二、Lambda表达式的语法及表达形式

Lambda表达式具有以下语法限制
1.不能有函数名,代表匿名类
2. 代表函数式接口实例
3. 返回值类型由编译器“推测”
4. 不能出现泛型,泛型定义在函数式接口中
5. 表达式内变量必须是final,不能在表达式内修改。或者显示定义为final,或
者“effectively final“变量,即默认final(local-non-final-initialized-only-once )
6. 没有自己的作用域,this或super指向lambda表达式外部
7. 表达式内部可以使用break, continue, return和throw等

表达形式
基本格式:
匿名函数 = (argument) -> (body)
常用几种写法如下:

在这里插入代码片() -> {} // void
() -> 42        // 表达式
() -> { return 42; }    // 有返回值,函数体块
() -> { System.gc(); }    // ⽆无返回值,函数体块
(int x) -> x+1 // 显示声明参数(declared types),表达式等价于返回值
(int x) -> { return x+1; }
(x) -> x+1     // 隐式声明参数(inferred-type)
x -> x+1      // 单隐式声明参数,括号可省略略
(int x, int y) -> x+y
(x,y) -> x+y
(x, final y) -> x+y    // 错误,隐式参数不能修改
(x, int y) -> x+y      // 错误,混用参数

三、Lambda表达式的实例应用

1.用lambda实现Runnable接口

//原始写法
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Java8之前写法");
            }
        }).start();
        //Java 8方式:
        new Thread( () -> System.out.println("Java8之后写法") ).start();
        new Thread( () -> {
            System.out.println("Java8之后写法");
        }).start();

2.消费型接口

//        有输入参数,没返回值
//        对应的方法类型为接收一个参数,没有返回值
//                一般来说使用Consumer接口往往伴随着一些期望状态的改变
//        或者事件的发生,典型的forEach就是使用的Consumer接口
//        虽然没有任何的返回值,但是向控制台输出结果
//        Consumer 使用accept对参数执行行为
public static void main(String[] args) {
		// 创建字符串
		String str = "gyk";
		
		// 调用
		testCon(str, (s) -> System.out.println(s));     //输出字符串
	}
	
	public static void testCon(String str, Consumer<String> con) {
		// 执行
		con.accept(str);
	}

3.供给型接口

//        无传入参数,有返回值
//        该接口对应的方法类型不接受参数,但是提供一个返回值
//        使用get()方法获得这个返回值
public static void main(String[] args) {
		// 创建字符串
		String str = "gyk";
		// 调用
		String sup = testSup(() -> str);
		System.out.println(sup);
	}
	
	public static String testSup(Supplier<String> sup) {
		// 执行
		String s = sup.get();
		return s;
	}

4.断言型接口

//        有传入参数,有返回值Boolean
//        该接口对应的方法为接收一个参数,返回一个Boolean类型值
//        多用于判断与过滤,使用test()方法执行这段行为
public static void main(String[] args) {
		// 创建字符串
		String str = "gyk";
		// 调用
		boolean flag = testPre(str, (s) -> s.length() > 0); //输入字符串,判断长度是否大于0		
		System.out.println(flag);
	}
	public static boolean testPre(String str, Predicate<String> pre) {
		// 执行
		boolean flag = pre.test(str);	
		return flag;
	}

四、使用Lambda表达式的意义

1.减少代码行数。相比匿名(内部)类,使用lambda表达式实例化函数式接口更更简洁
2. Stream API + Lambda 实现并行/串行操作
3. 传递lambda作为方法参数
4. 惰性计算,或延迟计算(lazy evaluation)

五、方法引用

某些lambda表达式里面仅仅是调用了一个已存在的方法,在这种情况下直接通过方法名称引用方法的形式可读性更高一些,这种形式就是方法引用。方法引用是一种更简洁易懂的lambda 表达式替换。
方法引用:引用类方法而不执行,类似取方法名
构造引用:引⽤用类构造方法而不实例化类,类似取构造方法名
方法引用类型:

1.TypeName::staticMethod - 类,接口,枚举的静态方法       //System::getProperty   
2.objectRef::instanceMethod - 对象实例方法         //System.out::println
3.ClassName::instanceMethod - 类的实例方法       //"abc"::length
4.TypeName.super::instanceMethod - 超类的实例方法
5.ClassName::new - 类构造方法                   //ArrayList::new
6.ArrayTypeName::new - 数组类型的构造方法                //int[]::new

关于Lambda表达式就介绍到这里,如发现博客中错误请尽管提出