Java8——Lambda表达式语法(一)

这章节用来讲解Lambda表达式的基本用法和Lambda表达式的语法格式。为接下来深度学习java8新特性做好准备。

一.初步学习Lambda表达式

java8中引用了一个新的操作符“->”,该操作符我们可以称为箭头操作符或者是Lambda操作符。

这个操作符又把Lambda表达式分为两部分

左侧: 表达式的参数列表(例如:我们用Lambda表达式去实现一个接口,完成接口中的实现方法,而左侧就是接口中的方法的形参列表)

右侧:表达式所需要执行的功能,即Lambda体。

注意:Lambda表达式需要函数式接口的支持。

什么是函数式接口:
1.只有一个方法的接口,我们称之为函数式接口

2.我们可以通过Lambda表达式去实现这个接口中的方法功能,并创建该接口的对象

3.我们可以在任意函数式接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口, 同时javadoc也会包含一条声明,说明这个接口是一个函数式接口

当函数式接口中如果有多条抽象方法,使用@FunctionalInterface注解的接口就会报错。

二.lambda表达式的基本语法格式

Lambda表达式的语法格式一:
无参数,无返回值。
()->system.out.println(“Hello Lambda!”);

例子:

	@Test
	public void test() {
	//典型例子:Runnable接口,只有一个run方法,无参数无返回值
		
		//原先创建一个Runnable接口实现run方法
	Runnable r=new Runnable(){
  int num=0;  //在JDK1.7中,我们匿名内部类调用局部变量必须加上final关键字
  //而在jdk1.8中,我们不再需要加上final,只要我们还未重新赋值的情况下,底层会自动帮我们加上final关键字
		@Override
		public void run() {
			System.out.println("Hello Runable!");
		}
		
	};
	r.run();
	System.out.println("===============================================");
	//现在用Lambda表达式实现Runnable接口
	Runnable r1= () ->System.out.println("Hello Lambda!");
	r.run();
	}

还有一点:在jdk1.7中,我们在匿名内部类中的局部变量要加上final关键字。而jdk1.8则不再需要了~

这里就不得不说一下,为什么局部变量在内部类中需要加上final关键字了:

局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用。

简单来说就是:
如果不是final局部变量,当方法执行完后,你的局部变量随着方法弹栈结束,局部变量也随之消失。但是内部类和我的方法并不是同时执行的,如果说没有加上final,这时候局部变量消失了,内部类又想要使用这个变量,那就惨了呀~

jdk1.8局部变量在内部类中不需要加上final关键字的原因:
而对于jdk1.8来说,对于内部类来说,局部变量不用再加上final关键字,不是因为不需要了,而是在java8底层自动帮助加上final关键字,只是对于我们程序员来说更加简便了。

Lambda表达式的语法格式二:
语法格式二:一个参数,无返回值
(x)->system.out.println(“Hello Lambda”);

在java8中有一个consumer接口(字意:消费者),而这个接口有一个方法,只有一个参数,无返回值。

@Test
	public void test1(){
		Consumer<String> c= (x) -> System.out.println(x);//传入一个字符串
			c.accept("Hello Lambda!");//调用接口中的方法
		}

Lambda表达式的语法格式三:
语法格式三:有两个以上的参数,并且有返回值,而且执行的功能操作有好几条语句。
(x,y) ->{
System.out.println(“通过Comparator接口比较两个数的大小”);
return Integer.compare(x, y);
};

@Test
	public void test2(){
		Comparator<Integer> com=(x,y) ->{
			System.out.println("通过Comparator接口比较两个数的大小");
			return Integer.compare(x, y);//利用Integer底层实现的compare方法进行比较
		};
	int i=	com.compare(1, 2);
		System.out.println(i);//-1,说明1<2
		
	}

注意:如果说有两个以上的参数,并且有返回值,但是执行的功能操作只有一条语句,那么return和{}可以省略不写。

	@Test
	public void test3(){//当Lambda表达式中有多个参数,但是执行的Lambda体只有一条,那么大括号和return可以省略不写
		Comparator<Integer> com1=(x,y)->Integer.compare(x, y);
		com1.compare(2, 3);
		System.out.println("当Lambda表达式中有多个参数,但是执行的Lambda体只有一条,那么大括号和return可以省略不写");
		System.out.println();
	}

在java8的lambda表达式中,你会发现,lambda表达式的参数类型根本不需要写,这是因为java8底层使用了“类型推断”。

	@Test
	public void test5(){
		Comparator<Integer> com1=(Integer x, Integer y)->Integer.compare(x, y);
		int i=com1.compare(2, 3);
		System.out.println(i);
		
//你会发现上面和下面执行的lambda表达式结果一样,都是-1。
//这是因为java8底层使用了“类型推断”,可以根据上下文来推断处参数的类型
		
		Comparator<Integer> com2=(x,y)->Integer.compare(x, y);
		int i2=com2.compare(2, 3);
		System.out.println(i2);
		
	}

在这里插入图片描述而在java7中,就已经开始使用类型推断了,例如常用的数组,集合:

	@Test
	public void test6(){
		String[] s={"aaa","bbb","ccc"};//底层自动推断处集合中的类型为String字符串
		List<String> list=new ArrayList<>();//自动根据上下文推断处ArrayList的集合元素类型
	}

自定义函数式接口

函数式接口在上文已经做处解释了,我们来自定义一个函数接口,来做一个运算方法。

1.先自定义一个函数式接口

/**
 * 定义一个接口,创建一个抽象方法,然后使用@FunctionalInterface注解,检查它到底是否是一个函数式接口
 */
@FunctionalInterface
public interface AdditionLambda {

	public int Addition(int x,int y);
	
	
	//因为我们给这个接口加上了一个@FunctionalInterface方法,如果这个接口中的抽象方法大于1个,那么就不是函数式接口,那么就会报错
	//public int 	subtraction(int x,int y);
		
	
}

2.对函数式接口使用Lambda表达式来完成运算方法

	@Test
	public void test4(){
		AdditionLambda add=(x,y)->x+y;
		int i=add.Addition(5, 10);
		System.out.println(i);//15
	}

3.编译结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨某人的快乐学习日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值