Java 8 新特性(二)Lambda表达式

一、Lambda表达式简介

个人理解,lambda表达式就是一种新的语法,没有什么新奇的,简化了开发者的编码,其实底层还是一些常规的代码。Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

  • Lambda表达式本质只是一颗让编程人员更加得心应手的“语法糖”,它只存在于Java源代码中,由编译器把它转换为常规的Java类代码。
  • Lambda表达式有点类似于方法,由参数列表和一个使用这些参数的主体(可以是一个表达式或一个代码块)组成
  • Lambda表达式与 Stream API 联合使用,可以方便的操纵集合,完成对集合中元素的排序和过滤等操作

Lambda表达式的语法

Lambda 表达式的基础语法:Java8中引入了一个新的操作符  "- >"  该操作符称为箭头操作符或 Lambda 操作符
箭头操作符将 Lambda 表达式拆分成两部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体

new Thread( ()  ->  System.out.println("thread"));

针对这种实行,我们怎么理解呢?其实很简单,上看一下上述lambda表达式的语法:() -> {}:

括号就是接口方法的括号,接口方法如果有参数,也需要写参数。只有一个参数时,括号可以省略。-> : 分割左右部分的,没啥好讲的。{} : 要实现的方法体。只有一行代码时,可以不加括号,可以不写return。

(parameters) -> expression

(parameters) ->{ statements; }

以下是lambda表达式的重要特征:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

案例

	@Test
	public void test1(){
		String[] data = {"marvin","jerry","sally","max","jason"};
		List<String> names = Arrays.asList(data);
		
		System.out.println("方式一:传统的遍历集合方式");
		for(String name : names){
			System.out.println(name);
		}
		
		System.out.println("方式二:使用Lambda表达式");
		names.forEach((name) -> System.out.println(name));
		
		System.out.println("方式三:使用Lambda表达式");
		names.forEach(System.out::println);
	}

解读:forEach 方法的参数是 Consumer 接口

public void forEach(Consumer<? super E> action)

 Consumer 接口中只有一个实现方法 void accept(T t);

而 names.forEach((name) -> System.out.println(name));相当于实现了accept方法

左边

name:是入参

右边

System.out.println(name) :是accept方法的实现

 

二、Lambda表达式中的方法引用

编译器能根据上下文来推断Lambda表达式的参数的场合时,可以在Lambda表达式中省略参数,直接通过 “::” 符号来引用方法

方法引用的语法格式有以下三种:

  • 第一种:objectName :: instanceMethod //对象引用实例方法
  • 第二种:ClassName :: staticMethod //类引用静态方法
  • 第三种:ClassName :: InstanceMethod //类引用实例方法

以下两种Lambda表达式是等价的

names.forEach((name)->System.out.println(name));
等同于:names.forEach(System.out::println);

x->System.out.println(x)

等同于:System.out :: println //引用实例方法

(x,y)->Math.max(x,y)

等同于:Math :: max //引用静态方法

x->x.toLowerCase()

等同于:String :: toLowerCase //引用实例方法

 

三、函数式接口(FunctionalInterface)

在JDK8中,定义了一个 @FunctionalInterface 注解

 

Lambda表达式 只能赋值给 声明为 函数式接口 的Java类型的 变量

如:Consumer、Runnable、Comparator、Predicate接口都标注为函数式接口,因此可以接收Lambda表达式

合法的赋值:Runnable race = () -> System.out.println("Hello world !");

非法的赋值:String str = () -> {return "hello".toUpperCase();};

因为String类没有标注为函数式接口,不能接收Lambda表达式,会导致编译错误 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值