Java 8 新特性(一)lambda表达式
Java 9 好像也快出了,不过我连Java 8的新特性都还没认真研究过,所以这几篇文章就是来介绍Java 8的新特性的。首先,第一个重要的特性就是传说中的lambda表达式了,虽然初学可能觉得这东西很难理解,但是一旦学会了,你就会发现离不开它了。
在现代编程语言中,lambda表达式这个语言特性已经成为了标配。当然不同语言中的lambda表达式概念和实现形式可能会稍有差别。不过不管在哪种语言中,我们都可以把lambda表达式简单的理解为匿名函数。在Java中,lambda表达式和只有一个方法的接口是差不多的,所以这样的接口又叫做SAM接口(Single Abstract Method interfaces)。
初识lambda表达式
说了半天,下面先来看看实际例子吧。我们在编写多线程代码的时候,常常需要编写实现Runnable的类。有时候为了省事,我们会写成匿名内部类的形式。
Runnable task1 = new Runnable() {@Overridepublic void run() {System.out.println("任务一");}
};
匿名内部类不好理解,而且写起来也非常丑陋。由于Runnable接口内只有一个方法,所以它是一个SAM接口,我们可以用lambda表达式改写它。那么改写之后是什么样子的呢?不要惊讶,只需要一行代码。
Runnable task2 = () -> System.out.println("任务二");
因此,我们可以看到lambda表达式的简洁之处。下面就来详细介绍一下lambda表达式的形式。
lambda表达式形式
lambda表达式可以用在需要SAM接口对象的地方,由于编译器这时候知道所需要的接口和对应方法的签名。所以lambda表达式的类型声明可以省略,具体类型由编译器自行推断。lambda表达式的基本形式如下。
(参数列表) -> {方法体}
为了方便说明,我这里定义了一组接口,用于之后的lambda表达式实现。
@FunctionalInterface
interface Interface1 {void f();
}@FunctionalInterface
interface Interface2 {void f(int a);
}@FunctionalInterface
interface Interface3 {void f(int a, int b);
}@FunctionalInterface
interface Interface4 {int f(int a, int b);
}
无参lambda
先来看看无参数的lambda表达式。特别地,如果方法体只有一行代码,可以省略方法体的大括号。
Interface1 interface1 = new Interface1() {@Overridepublic void f() {System.out.println("f");}
};
Interface1 lambda1 = () -> {System.out.println("f");
};
//如果方法体只有一行代码,可以省略大括号
Interface1 lambda1a = () -> System.out.println("f");
多个参数的lambda
我们可以看到由于编译器可以进行类型推断,所以lambda表达式的参数列表不需要参数类型声明,而且由于我只有一行代码,所以大括号也省略了。
//多个参数lambda
Interface3 interface3 = new Interface3() {@Overridepublic void f(int a, int b) {System.out.println(a + b);}
};
Interface3 lambda3 = (a, b) -> System.out.println(a + b);
带返回值的lambda
带返回值的lambda表达式其实和普通的一样,只不过需要在方法体的最后使用return语句。值得注意的是最后一个例子,如果方法体本身足够简单,可以直接将返回值表达式写在lambda表达式的右边,编译器也会正确对待这种情况。
//带有返回值的lambda
Interface4 interface4 = new Interface4() {@Overridepublic int f(int a, int b) {return a + b;}
};
Interface4 lambda4 = (a, b) -> {return a + b;
};
Interface4 lambda4a = (a, b) -> a + b;
单个参数的lambda
如果lambda表达式只有一个参数,那么参数列表的小括号也可以省略,例如下面的第二个例子。下面第三个例子演示了另一个新语法方法引用,如果lambda表达式的形式是单个参数a -> 某个只有一个参数的方法(a),那么就可以简写成方法引用的形式类::方法。方法引用是一个新语法,如果见到了不要奇怪,这也是正确的Java代码。
//一个参数的lambda
Interface2 interface2 = new Interface2() {@Overridepublic void f(int a) {System.out.println(a);}
};
Interface2 lambda2 = (a) -> System.out.println(a);
Interface2 lambda2a = a -> System.out.println(a);
Interface2 methodReference = System.out::println;
函数接口
@FunctionalInterface注解
如果查看JDK源码的一些接口,会发现它们上面添加了@FunctionalInterface注解。例如上面提到的Runnable接口。
@FunctionalInterface
public interface Runnable {public abstract void run();
}
这个注解用于标注函数接口,也就是上面提到的SAM接口。如果一个接口中包含了不止一个方法,那么函数接口注解就会触发编译错误。这个功能类似于@Override注解。当然并不是说要使用lambda表达式必须标记这个注解,只要接口中只有一个方法,那么就可以使用lambda表达式。
其实函数接口可以包括不止一个方法,除了一个普通的抽象方法之外,函数接口还可以包含一个在java.lang.Object类中声明的方法。Java 8新增了默认方法特性,如果接口的实现类没有实现java.lang.Object类中的这些基本方法,那么就会调用java.lang.Object类中的实现作为默认实现。
@FunctionalInterface
interface Interface5 {void f();String toString();
}
预定义的函数接口
在java.util.function包下定义了大量预定义的函数接口,它们包含了各种各样的形式,基本涵盖了编程的各个方面。同学们最好对这些函数接口的形式稍作了解,以后碰到的时候就不会一头雾水了。
lambda表达式应用
编写线程
前面提到了,可以使用lambda表达式简化线程代码的编写,不再需要冗长的匿名内部类。
//编写线程
Runnable task = () -> System.out.println("简单的任务");
Executor executor = Executors.newCachedThreadPool();
executor.execute(task);
编写比较器
比方说我们有一个学生类,有姓名和年龄两个字段。如果需要按照某种规则来进行排序,可以使用比较器Comparator接口来比较,利用lambda表达式同样可以简化这部分代码的编写。
class Student {private String name;private int age;//其余方法已省略
}
可以看到比较规则只需要一条lambda表达式即可传入,非常方便。后面两个例子是Comparator接口新增的工具方法,可以帮助我们简化比较代码的编写,这里使用了方法引用来简化代码。comparing等方法的返回值仍然是Comparator,所以可以链式调用进行多级比较。
List<Student> students = new ArrayList<>();
students.add(new Student("yitian", 25));
students.add(new Student("anna", 26));
students.add(new Student("wang5", 24));students.sort((a, b) -> a.getAge() - b.getAge());
System.out.println(students);students.sort(Comparator.comparing(Student::getName));
System.out.println(students);students.sort(Comparator.comparing(Student::getName).thenComparing(Student::getAge));
System.out.println(students);
作者:乐百川
链接:https://www.jianshu.com/p/583dad6dcd8b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Java 8 新特性(一)lambda表达式相关推荐
- 深圳Java培训学习:Java8.0新特性之Lambda表达式--【千锋】
深圳Java培训学习:Java8.0新特性之Lambda表达式–[千锋] 前言 Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.本篇文章,主要给大家介绍的是lambda表 ...
- java x=8_Java8新特性之lambda表达式
简介 Java8带来的新特性之一Lambda表达式,又称之为函数式编程,核心思想是将面向对象中的传递对象变为传递行为 语法 expression = (variable) -> anction ...
- java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合
java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...
- JDK8新特性之Lambda表达式
转载自 JDK8新特性之Lambda表达式 什么是Lambda表达式 Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁.当开发者在编写Lambda表达式时,也会随之被编译成 ...
- 【java8新特性】——lambda表达式与函数式接口详解(一)
一.简介 java8于2014年发布,相比于java7,java8新增了非常多的特性,如lambda表达式.函数式接口.方法引用.默认方法.新工具(编译工具).Stream API.Date Time ...
- java8新特性之lambda表达式--超级详细版本
java8新特性之lambda表达式 1.什么是lambda表达式?为什么用它? 2. 为什么Java需要lambda表达式? 3. lambda表达式的语法 4.函数式接口 4.1 什么是函数式接口 ...
- Java8 新特性:Lambda 表达式、方法和构造器引用、Stream API、新时间与日期API、注解
Java8新特性:Lambda 表达式.方法和构造器引用.Stream API.新时间与日期API.注解 1.Java8新特性 1.1.主要的新特性: 1.2.编程风格 2.Lambda 表达式 2. ...
- Java 8 新特性之Lambda
Java 8 新特性之Lambda.Stream.Optional Java 8 新特性之Lambda.Stream.Optional 速度更快 代码更少(增加了新的语法Lambda表达式) 强大的S ...
- java:java8新特性(Lambda 表达式、方法引用、构造器引用、数组引用、Stream API)
速度更快 对 HashMap .ConcurrentHashMap低层的数据结构(数组+链表+二叉树) 低层的内存结构(将永久区更新为元空间,元空间使用的是物理内存) 代码更少(增加了新的语法 Lam ...
- lambda 对象去重_最火的java8新特性:Lambda 表达式
主要内容 1. Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 其他新特性 Java 8新特性简介 速度更快 代码更少(增加了新的语法 Lambd ...
最新文章
- GridControl 选择列、复选框全选(上)
- PyTorch框架学习二——基本数据结构(张量)
- 20个响应式网页设计中的“神话”误区
- django目录介绍
- 加减法计算器-java
- MPLS ××× 基本实验测试
- 你的IE一路顺风吗?
- awr报告 解读_Oracle Awr报告_awr报告解读_基础简要信息
- 2 4G高频PCB天线设计
- Sopcast for linux更新至3.01!
- MongoDB学习笔记
- 为什么算法这么难???
- 仪表板展示|DataEase可视化数据分析工具中的仪表板跳转和联动设置
- JavaWeb_基础知识
- TypeScript 2
- csp2021-09-4 收集卡牌
- 6-5 Approximating Eigenvalues (40分)
- 博弈论--从 必胜点与必败点 到 SG 函数
- 华为计算机apk,华为手机助手安卓版apk
- 太准了这十个心理暗示