JDK8新特性-lambda表达式

一、函数式接口

1.1 概念
函数式接口:有且仅有一个抽象方法的接口,并被 @FunctionalInterface 修饰。
要学习lambda表达式,要先了解函数式接口。

1.2 JDK8中接口的变化

public interface MyInterface1 {
	void f1();  //普通抽象方法
	static void f2() { //被static修饰的方法允许有方法体
	}
	default void f3() { //被default修饰的方法允许有方法体
	}
}

得出结论:jdk8允许接口中写实现的方法,但是必须被 static 或者 default 修饰。

1.3 编写一个函数式接口

@FunctionalInterface
public interface MyInterface2 {
	void f1();
}
//满足:有且仅有一个抽象方法

1.4 使用匿名内部类继承实现函数式接口

MyInterface2 my = new MyInterface2() {	
	@Override
	public void f1() {
		System.out.println("f1...");
	}
};

为什么使用匿名内部类呢?一句话:方便。
在仅调用一次的场景下,匿名内部类的方式就非常方便,不用去新建一个类实现该接口后再去重写方法。
但是,我们会发现,在函数式接口的背景下,使用匿名内部类仍然不是很简化。所以,我们使用lambda表达式来进一步简化代码。

二、lambda表达式

2.1 概念
Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。
一句话:在java中主要用于简化 函数式接口的匿名内部类的编写。

2.2 语法

(参数列表)->{
	方法体
}

2.3 代码实现
2.3.1 无参无返回值的方法

@FunctionalInterface
public interface MyInterface {
	//无参无返回值
	void f1();
}
//1.使用匿名内部类实现
MyInterface1 myInterface1 = new MyInterface1() {
	@Override
	public void f1() {
		System.out.println("f1...");
	}
};
//2.使用lambda表达式进行实现(省略new接口和方法签名的部分,中间用 -> 连接 )
MyInterface1 myInterface1 =() -> {
	System.out.println("f1...");
};
//进一步简化:方法体仅有一个行代码 {} 可以省略
MyInterface1 myInterface1 =() -> System.out.println("f1...");

2.3.2 无参有返回值的方法

@FunctionalInterface
public interface MyInterface1 {
	//无参有返回值
	int f2();
}
//1.匿名内部类实现
MyInterface1 myInterface1 = new MyInterface1() {
	@Override
	public int f2() {
		return 0;
	}
};
//2.lambda表达式实现
MyInterface1 myInterface1 = () -> return 0;
//当方法体仅有一行代码,return 也可以省略
MyInterface1 myInterface1 = () -> 0;

2.3.3 有参无返回值的方法

@FunctionalInterface
public interface MyInterface1 {
	//有参无返回值
	void f3(int a);
}
//1.匿名内部类实现
MyInterface1 myInterface1 = new MyInterface1() {
	@Override
	public void f3(int a) {
		System.out.println(a);
	}
};
//2.lambda表达式实现
MyInterface1 myInterface1 = (int a) -> System.out.println(a);
//有参时,参数的类型可以省略
MyInterface1 myInterface1 = (a) -> System.out.println(a);
//当参数仅有一个时,()可以省略
MyInterface1 myInterface1 = a -> System.out.println(a);

2.3.4 有参有返回值的方法

@FunctionalInterface
public interface MyInterface1 {
	//有参有返回值
	int f4(int a,int b);
}
//1.匿名内部类实现
MyInterface1 myInterface1 = new MyInterface1() {
	@Override
	public int f4(int a, int b) {
		return a+b;
	}
};
//2.lambda表达式实现
MyInterface1 myInterface1 = (int a, int b) -> {
	return a+b;
};
//最终简化为:多个参数时()不能省略
MyInterface1 myInterface1 = (a, b) -> a+b ;

三、lambda表达式中使用调用方法

3.1 调用构造方法
需求:将字符串转为Integer

@FunctionalInterface
public interface MyInterface {
	//将字符串转为Integer
	Integer pasreInt(String str);
}
//1.匿名内部类实现
MyInterface myInterface = new MyInterface() {
	@Override
	public Integer pasreInt(String str) {
		return new Integer(str);
	}
};
//2.lambda表达式实现
MyInterface myInterface = str -> new Integer(str);
//继续简化:
MyInterface myInterface = Integer::new;  //语法为:  类名::new

3.2 调用静态方法
需求:把字符串转为 int

@FunctionalInterface
public interface MyInterface {
	//将字符串转为int
	int parse(String str);
}
//1.匿名内部类实现
MyInterface myInterface = new MyInterface() {
	@Override
	public int parse(String str) {
		//将字符串转为:int
		return Integer.parseInt(str);
	}
};
//2.lambda表达式实现
MyInterface myInterface = str -> Integer.parseInt(str);
//继续简化:
MyInterface myInterface = Integer::parseInt;  //语法: 类名::静态方法名

3.3 调用实例方法
需求:判断字符串是不是以 .mp4 结尾 , 这里咱们用到一个由java提供的函数式接口 Function 来完成。

String str = "1.mp4";
Function<String, Boolean> fun = new Function<String, Boolean>(){
	@Override //判断str是不是以 .mp4 结尾
	public Boolean apply(String t) {
		return str.endsWith(t);
	}
};
System.out.println(fun.apply(".mp4"));
//lambda表达式简化:
String str = "1.mp4";
Function<String, Boolean> fun = t -> str.endsWith(t); 
System.out.println(fun.apply(".mp4"));
//继续简化:
String str = "1.mp4";
Function<String, Boolean> fun = str::endsWith;  // 语法为: 对象名::方法名
System.out.println(fun.apply(".mp4"));

实例方法的特殊情况:
需求:判断字符串是否为空。

Function<String, Boolean> function = new Function<String, Boolean>(){
	@Override 
	public Boolean apply(String t) {
		return t.isEmpty();
	}
};
//lambda表达式简化:
Function<String, Boolean> function = t -> t.isEmpty();
//继续简化:
Function<String, Boolean> function =  String::isEmpty; //语法: 类名::实例方法名 (语法和静态方法很像要注意区分)

四、做个练习巩固一下

需求:遍历List集合

List<Integer> list = Arrays.asList(1,2,3,4);
//list集合给我们提供了一个forEach()方法可以遍历集合,实现函数式接口Consumer
//匿名内部类的方式:
list.forEach(new Consumer<Integer>() {
	@Override
	public void accept(Integer t) {
		System.out.println(t);
	}
});
//使用lambda简化:
list.forEach( t -> System.out.println(t) );
//再简化:满足lambda中调用实例方法的规则
list.forEach(System.out::println);

如果你掌握了lambda,接着你就可以去看看Stream流了,点击:学习Stream流

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值