Java 中的 Lambda 表达式
Lambda表达式
Lambda 表达式是 JDK1.8 的一个新特性,又称特殊的匿名内部类,可以取代大部分的匿名内部类,语法更简洁,可以写出更优雅的 Java 代码,可以极大地优化代码结构。
Lambda 表达式不会生成单独的内部类文件,但匿名内部类会。
Lambda表达式特性
★ Lambda 表达式没有显示的方法名。
★ Lambda 表达式很像一个函数,具有参数列表、函数体、返回类型、异常,但没有函数名。
★ Lambda 表达式可以作为方法的参数,也可以作为变量存储。
★ Lambda 表达式的代码更加简洁和精确。
Lambda表达式的定义
基本语法:
<函数式接口> <变量名> = (参数1, 参数2...) -> {
//方法体
};
或
<函数式接口> <变量名> = (参数1, 参数2...) -> 表达式;
注意事项:
✔ Lambda 表达式由三部分构成:参数列表、箭头(->)、Lambda 体。
✔ Lambda 体,可以是一个表达式,也可以是一个语句块。
✔ Lambda 体,表达式中不能加入 return 语句,因为在表达式中已经隐含了 return 语句;但是,语句块中没有隐含,需要使用 return 语句。
✔ Lambda 表达式并不是对所有接口都可以实现,接口需要满足一个条件才能被Lambda 表达式实现:Lambda 规定接口中只能有一个需要被实现的方法。注意,并不是规定接口中只能有一个方法。
特别提醒:
jdk1.8 中的另一个新特性:default,被 default 修饰的方法会有默认实现,不是必须被实现的方法。在实现Lambda 表达式的时候需注意。
Lambda 表达式的使用
1.无参,有返回值
@FunctionalInterface public interface LambdaTest { // 无参,有返回值 int method(); }
public class test { public static void main(String[] args) { LambdaTest test = ()-> 20; int result = test.method(); System.out.println(result); } }
@FunctionalInterface注解:
修饰函数式接口的,要求接口中的抽象方法只有一个。这个注解往往和 lambda 表达式一起出现。
2.无参,无返回值
@FunctionalInterface public interface LambdaTest { // 无参,无返回值 void method(); }
public class test { public static void main(String[] args) { LambdaTest test = () -> {}; test.method(); } }
3.单参,有返回值
@FunctionalInterface public interface LambdaTest { // 单参,有返回值 int method(int a); }
public class test { public static void main(String[] args) { // 表达式形式 LambdaTest test = a -> a+10; System.out.println(test.method(10)); // 代码块形式 LambdaTest test2 = a -> { return a+10; }; System.out.println(test2.method(10)); } }
4.多参,有返回值
@FunctionalInterface public interface LambdaTest { // 多参,有返回值 int method(String a, String b); }
public class test { public static void main(String[] args) { // 表达式形式 LambdaTest test = (a, b) -> a.length() - b.length(); System.out.println(test.method("abb", "bbccdd")); // 代码块形式 LambdaTest test2 = (a, b) -> { return a.length() - b.length(); }; System.out.println(test2.method("abb", "bbccdd")); } }
表达式使用技巧总结
★ 形参列表的数据类型会自动判断。
★ 如果形参列表为空,只需保留()。
★ 如果形参只有一个,()可以省略,只需要参数的名称即可。
★ 如果执行语句只有一句,且无返回值,则{}可省略;如果有返回值,若想省略{},则必须同时省略return,且执行语句也必须保证只有一句。
Lambda 表达式应用
方法引用
有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用 lambda表达式的接口快速指向一个已经被实现的方法。
引用语法:
方法归属者::方法名
静态方法的归属者为类名,普通方法归属者为对象。
常见形式:
对象 :: 实例方法
类 :: 静态方法
类 :: 实例方法
类 :: new
引用要求:
① 参数数量和类型要与接口中定义的一致。
② 返回值类型要与接口中定义的一致。
代码示例:
public class MethodReferences { public static void main(String[] args) { // 1.对象::实例方法 Consumer<String> consumer = s->System.out.println(s); consumer.accept("hello"); Consumer<String> consumer2 = System.out::println; consumer2.accept("world"); // 2.类::静态方法 Comparator<Integer> com = (o1, o2)->Integer.compare(o1, o2); Comparator<Integer> com2 = Integer::compare; // 3.类::实例方法 Function<String, String> function = e->e.toUpperCase(); Function<String, String> function2 = String::toUpperCase; System.out.println(function2.apply("hello")); // 4.类::new Supplier<String> supplier = ()->new String(); Supplier<String> supplier2 = String::new; System.out.println(supplier2.toString()); } }
创建线程
public class TestLambda { public static void main(String[] args) { // 匿名内部类 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("子程序执行。。。"); } }; // Lambda表达式 Runnable runnable2 = ()->System.out.println("子程序执行2。。。"); new Thread(runnable2).start();
new Thread(()->System.out.println("子程序执行3。。。")).start(); } }
集合操作
可以调用集合的
public void forEach(Consumer<? super E> action)方法,通过 Lambda 表达式的方式遍历集合中的元素。Consumer 接口是 jdk 为我们提供的一个函数式接口。
public class test { // 集合遍历 public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); Collections.addAll(list, 4, 3, 9, 0, 5); // 方法引用 list.forEach(System.out::println); // Lambda表达式 list.forEach(element -> { if (element % 2 == 0) { System.out.println(element); } }); } }
public class test { // 集合排序 public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); Collections.addAll(list, 4, 3, 9, 0, 5); // 匿名内部类 list.sort(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } }); // lambda表达式 list.sort((o1,o2)->o1-o2); list.forEach(System.out::println); } }
- Java8中用Lambda表达式合并多个相同属性的对象集合
- 【JAVA8】Java Lambda表达式入门
- java lambda表达式示例
- Java8新特性-Lambda表达式-Stream API等(学习笔记)
- Android Studio使用gradle-retrolambda支持Java8 新特性 Lambde表达式
- Java-函数式编程(二)Lambda表达式
- 浅谈Java 7的闭包与Lambda表达式之优劣
- Java Lambda表达式入门
- Java---lambda表达式
- Java学习笔记(Lambda表达式、File类、IO流)
- Java8学习(3)- Lambda 表达式
- Java8 Lambda 表达式初识
- Java中Lambda表达式的使用
- java8 Lambda表达式的新手上车指南(1)--基础语法和函数式接口
- Java 8 lambda 表达式示例
- Java8 Lambda表达式示例
- Java 进阶,学习笔记-12 函数式编程以及 Lambda 表达式
- Java Lambda 表达式(三):目标类型(Target Type)
- Java 8来了!!! 极客学院推出中国第1个Java8课程,详解Lambda 表达式
- Java lambda表达式