Lambda表达式
1、概念
lambda表达式的语法由参数列表、->和函数体组成。函数体既可以是一个表达式,也可以是一个语句块:
- 表达式:表达式会被执行然后返回执行结果。
- 语句块:语句块中的语句会被依次执行,就像方法中的语句一样
return语句会把控制权交给匿名方法的调用者。
break和continue只能在循环中使用。 - 如果函数体有返回值,那么函数体内部的每一条路径都必须返回值。
以下是lambda表达式的重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
表达式函数体适合小型lambda表达式,它消除了return关键字,使得语法更加简洁。
1.1 不包含参数且主体为表达式
Lambda表达式不包含参数,使用空括号 ()表示没有参数。
@FunctionalInterface
interface OnClickListener {
void doOnClick();
}
//该Lambda表达式实现了OnClickListener接口,该接口也只有一个doOnClick方法,没有参数,且返回类型为void。
public static void main(String[] args) {
OnClickListener clickListener = () -> System.out.println("OnClickListener");
clickListener.doOnClick();
}
//其主体为一段代码段,在其内用返回或抛出异常来退出。 只有一行代码的Lambda表达式也可使用大括号, 用以明确Lambda表达式从何处开始、到哪里结束。
OnClickListener clickListener1 = () -> {
System.out.println("插上电源");
System.out.println("打开电视");
};
clickListener1.doOnClick();
1.2 包含一个参数且主体为表达式
Lambda表达式可以包含一个参数,将参数写在()内,如果只有一个参数可以将()省略。
public interface OnItemClickListener {
void doItemClickListener(int position);
}
OnItemClickListener mItemListener = position -> "position = [" + position + "]";
System.out.println(mItemListener.doItemClickListener(123));
1.3 包含多个参数且主体为表达式
Lambda表达式可以包含多个参数,将参数写在()内,此时()不可以省略。
interface IMathListener {
int doMathOperator(int start, int plusValue);
}
IMathListener mPlusListener = (x, y) -> x + y;
int sum = mPlusListener.doMathOperator(10, 5);
1.4 包含多个参数,指定参数类型且主体为代码段
IMathListener mMaxListener = (x, y) -> {
if (x > y) {
return x + 12 ;
} else {
return y - 10;
}
};
System.out.println( mMaxListener.doMathOperator(10, 20));
2、Java8方法引用
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文。计算时,方法引用会创建函数式接口的一个实例。
当Lambda表达式中只是执行一个方法调用时,不用Lambda表达式,直接通过方法引用的形式可读性更高一些。方法引用是一种更简洁易懂的Lambda表达式。
==注意方法引用是一个Lambda表达式,其中方法引用的操作符是双冒号"::"。==方法引用的标准形式是:类名::方法名。(注意:只需要写方法名,不需要写括号)
有以下四种形式的方法引用:
类型 | 示例 |
---|---|
引用静态方法 | ClassName::staticMethodName |
引用某个对象的实例方法 | Object::instanceMethodName |
引用某个类型的任意对象的实例方法 | ClassName::methodName |
引用构造方法 | ClassName::new |
2.1 引用静态方法
Callback<char[], String> consumer = String::valueOf;
System.out.println(consumer.call(new char[]{'A','b'}));
ToIntFunction<String> toInt = Integer::parseInt;
System.out.println(toInt.applyAsInt("33"));
2.2 引用特定对象的实例方法
List<String> list = new ArrayList<>();
Predicate<String> predicate = list::add;
predicate.test("ccc");
2.3 引用特定类型的任意对象的实例方法
若Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的参数时,可以使用对象方法引用。
BiPredicate<String,String> biPredicate = String::equals;
boolean test = biPredicate.test("aaa", "bbb");
2.4 引用构造函数
Supplier<Person> sup = Person::new;
Person person = sup.get();
person.setName("张三丰");
System.out.println(person.getName());