【Java8新特性】 Lambda表达式
一、Lambda 表达式 是什么?
Lambda读音:拉姆达。
- Lambda是一个匿名函数,匿名函数就是一个没有名字的函数。
- Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
- Lambda 表达式可以使代码变的更加简洁紧凑。
语法
lambda 表达式的语法格式如下:
(parameters) -> expression 或 (parameters) ->{ statements; }
Java8 中引入了一个新的操作符 ->, 该操作符称为箭头操作符或 Lambda 操作符。
箭头操作符将 Lambda 表达式拆分成两部分:
左侧 : Lambda 表达式的参数。
右侧 : Lambda 表达式中所需执行的操作, 即 Lambda 体。
lambda表达式的重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体只有一个语句,可以不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
二、Lambda 表达式实例
Lambda 表达式的简单例子:
// 1. 无参数,无返回值 () -> System.out.print(Hello Lambda); // 2. 无参数,有返回值,返回值 5 () -> 5; // 3. 一个参数(箭头左侧括号可以省略),返回“参数+1”后的值 x -> x + 1 // 4. 两个参数(多个参数时,箭头左侧括号不可以省略),返回它们的差值 (x, y) -> x - y // 5. 三个int型整数(支持多个参数),返回它们的和 (int x, int y, int z) -> x + y + z // 6. 接收一个 string 对象,并在控制台打印,不返回任何值(大括号可以省略) (String s) -> System.out.print(s) 或 (String s) -> { System.out.print(s); }
注 : Lambda 表达式中的参数类型都是由编译器推断得出的。 Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。 Lambda 表达式的类型依赖于上下文环境,是由编译器推断出来的,这就是所谓的 “类型推断”。
三、函数式接口(function interface)
Lambda 表达式需要 “函数式接口” 的支持。
函数式接口 : 接口中只有一个抽象方法的接口,称为函数式接口,可以通过 Lambda 表达式来创建该接口的对象。
可以使用 @FunctionalInterface 注解来检查该接口是否为函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口,可以有效避免其它开发人员在该接口中新增额外的方法。
简单示例
接口:
//自定义函数式接口 @FunctionalInterface public interface MyFun { void run(); }
应用:
public static void main(String[] args) { //jdk8之前 testMyFun(new MyFun() { @Override public void run() { System.out.println(这是自定义函数接口); } }); //java8使用lambada表达式,代码更简洁 testMyFun(() -> System.out.println(这是自定义函数接口)); } private void testMyFun(MyFun myFun) { myFun.run(); }
四、java8四大内置核心函数式接口
java8为我们定义好了4类内置函数式接口,这4类接口基本能够满足平时的开发需要,如果有比较特殊的情况我们可以自己去定义函数式接口。
1、consumer
@FunctionalInterface public interface Consumer<T> { /** * Performs this operation on the given argument. * * @param t the input argument */ void accept(T t); }
应用示例:
public static void main(String[] args) { consumTest(1000,x-> System.out.println(消费了:+x+元)); } public void consumTest(int money, Consumer consumer){ consumer.accept(money); }
2、Supplier
@FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); }
应用示例:
public static void main(String[] args) { int i = supplyTest(() -> (int) (Math.random() * 10);); System.out.println(获得的随机数是:+i); } public int supplyTest(Supplier<Integer> supplier){ return supplier.get(); }
3、Function<T, R> 函数型接口,有入参,有返回值
@FunctionalInterface public interface Function<T, R> { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ R apply(T t); }
应用示例:计算一个数的2倍,并输出结果
public static void main(String[] args) { int num = functionTest(5, x -> x * 2); System.out.println(计算后的结果值是:+num); } public int functionTest(int a,Function<Integer,Integer> function){ return function.apply(a); }
4、Predicate
@FunctionalInterface public interface Predicate<T> { /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); }
应用示例:判断一个数是否大于10,并输出真假
public static void main(String[] args) { boolean flag = predicateTest(20, x -> x > 10); System.out.println(20比10大吗:+ flag); } public boolean predicateTest(int x,Predicate<Integer> predicate){ return predicate.filter(x); }