lambda表达式,函数式接口及方法引用相关介绍

lambda表达式是Java8提出的新特性,表示一个可传递的代码块(函数)

lambda表达式

//借助比较器类实现Arrays.sort
public class normal {
	public static void main(String[] args) {
		String[] array = {"abc", "d", "ef"};
		Arrays.sort(array, new LenComparator());
		for(String a : array) {
			System.out.println(a);
		}
	}
}

class LenComparator implements Comparator<String>{
	public int compare(String first, String second) {
		if(first.length() > second.length()) return 1;
		else if(first.length() < second.length()) return -1;
		else return 0;
	}
}
//lambda表达式实现Arrays.sort
public static void main(String[] args) {
		String[] array = {"abc", "d", "ef"};
		Arrays.sort(array, (String first, String second) -> first.length() - second.length());
		for(String a : array) {
			System.out.println(a);
		}
	}
//得到同样结果
d
ef
abc

两者同样是将一段代码传入到sort方法中,在Java中表示一段代码就必须创建一个对象并实例化才能实现传入,这个过程较为复杂也并不直观。而lambda表达式(String first, String second) -> first.length() - second.length()代替了比较器类,实现了一个代码块简介的表示和传递


lambda表达式基本语法

参数及其类型 + 箭头 + 代码块

  • 无参数时仍需(),如果参数类型可由上下文推导则可省略类型,若为单个参数可省去()
  • 可以使用单个表达式,也可以用{ }内的代码块,用{}时必须return
  • 返回类型可由上下文推导则可省略return,但如果使用return则所有分支必须包含return

像上文例中的Arrays的比较器——Comparator接口,用lambda表达式替换了该接口的一个实现抽象方法的实例,这种接口就是函数式接口

函数式接口

只有一个抽象方法的接口(Comparator中有compare和equal两个抽象方法,但equal属于Object覆盖方法,不会计入接口的抽象方法数量)

//同样的效果不同写法,这里的Comparator就是函数式接口,lambda表达式即可看作是类型为函数式接口的数据
public static void main(String[] args) {
		Comparator<String> cp = (first, second) -> first.length() - second.length();
		String[] array = {"abc", "d", "ef"};
		Arrays.sort(array, cp);
		for(String a : array) {
			System.out.println(a);
		}
	}

java提供很多中类型的函数式接口,按照不同参数类型返回类型及特殊方法区分,
详见Java 8 函数式接口。调用函数式接口作为参数,在方法中调用接口中的方法,即可在方法中使用lambda表达式。常见的像list.removeif方法使用Predicate函数式接口,删除满足特定条件的列表成员。也可以编写自己的函数式接口,可以使用@FuncationalInterface注解,静态检查抽象方法个数是否符合规定。


如果lambda表达式中的代码块所要执行的功能,在已有的类方法中已经出现,为了简化代码,可以直接调用该方法,即直接引用方法。

方法引用

当lambda表达式的参数形式与方法参数形式相同时

  • object.instanceMethod
  • Class.staticMethod

特别的,

  • Class.instanceMethod 第一个参数作为方法的目标
//使用方法引用达成同一效果
public class method {	
	public static void main(String[] args) {
		String[] array = {"abc", "d", "ef"};
		Arrays.sort(array, length::lengthSort);
		for(String a : array) {
			System.out.println(a);
		}
	}
}

class length{
	public static int lengthSort(String first, String second) {
		return first.length() - second.length();
	}
}

ps. Class::new 表示类构造器的引用


lambda表达式中的变量

  • 只能引用值,改变值时会报错,可以用方法引用来实现值改变
  • 使用的变量必须为最终变量,之后不能再修改的变量,否则报错
  • 使用lambda表达式重点在于延迟执行,可能表达式在创建对象已经回收后才执行。但不用担心表达式调用对象中变量消失问题,因为lambda表达式在创建时就把使用到的变量捕获了。

									————《Java核心技术》第六章 总结
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值