java8函数式编程-lambda表达式简介
1.1、概述
Lambda是jdk8中一个语法糖,可以对某些匿名内部类的写法进行简化,是函数式编程思想的一个体现,这使得我们可以不用关注什么对象,而是更关注我们对数据进行了什么操作
1.2、核心原则
可推导可省略
1.3、基本格式
(参数列表)->{代码}
idea: alt+enter替换
例一
我们可以在创建线程并启动时使用匿名内部类的写法:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Lambda测试开始");
}
}).start();
使用Lambda修改之后
new Thread( ()->{System.out.println("Lambda测试结束");} ).start();
例二
现有方法定义如下 ,其中IntBinaryOperator是一个接口。先使用匿名内部类调用该方法
public static int calculateNum(IntBinaryOperator operator){
int a = 10;
int b = 20;
return operator.applyAsInt(a, b);
}
public static void main(String[] args) {
int i = calculateNum(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left+right;
}
});
System.out.println(i);
}
Lambda写法:
public static void main(String[] args) {
int i = calculateNum((int left, int right) -> {
return left + right;
});
System.out.println(i);
}
例三
现有方法定义如下,其中InterPredicate是一个接口,先试用匿名内部类调用该方法
public static void PrintNum(IntPredicate pred) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i : arr) {
if (pred.test(i)) {
System.out.println(i);
}
}
}
public static void main(String[] args) {
PrintNum(new IntPredicate() {
@Override
public boolean test(int value) {
return value % 2 == 0;
}
});
}
Lambda写法:
public static void main(String[] args) {
PrintNum(value -> {value % 2 == 0} );
}
1.4、省略规则
- 参数类型可以省略
- 参数只有一个时,( ) 可以省略
- 方法体只有一句代码时,{ } 可以省略
- 方法体重唯一语句是return时,省略大括号的同时return也要省略
1.5、方法引用
有时候多个lambda表达式实现函数是一样的话,可以封装成通用方法,以便于维护,这时候可以用方法引用实现
语法:对象 : : 方法
假如是static方法,可以直接 类名 : : 方法
实例如下:
// 对象::方法
public class test {
public static void main(String[] args) {
test class_test = new test();
If if1 = class_test::method;
System.out.println(if1.test(1));
}
public int method(int a) {
return a - 2;
}
interface If {
int test(int a);
}
}
// 类名::方法
public class test {
public static void main(String[] args) {
If if1 = test::method;
System.out.println(if1.test(1));
}
public static int method(int a) {
return a - 2;
}
interface If {
int test(int a);
}
}
1.6、构造方法引用
如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用
语法:类名::new
实例:
首先定义一个Person( name, age )实体类,实现有参和无参构造方法和toString
// 实体类部分代码
private String name;
private int age;
public Person() {
System.out.println("无参构造方法");
}
public Person(String name, int age) {
System.out.println("有参构造方法");
this.name = name;
this.age = age;
}
public class test {
// 1、一般写法
public static void main(String[] args) {
PersonService1 personService1 = new PersonService1() {
@Override
public Person getPerson() {
return new Person();
}
};
System.out.println(personService1.getPerson());
}
// 2、 lambda表达式
public static void main(String[] args) {
PersonService1 personService1 = () -> new Person();
System.out.println(personService1.getPerson());
}
// 3、类名::new
public static void main(String[] args) {
PersonService1 personService1 = Person::new;
System.out.println(personService1.getPerson());
PersonService2 personService2 = Person::new;
System.out.println(personService2.getPerson("Akiko",18));
}
interface PersonService1 {
Person getPerson();
}
interface PersonService2 {
Person getPerson(String name, int age);
}
}
1.7、综合实例
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person("aa", 1));
list.add(new Person("bb", 4));
list.add(new Person("cc", 3));
list.add(new Person("dd", 2));
list.sort((o1, o2) -> o1.getAge() - o2.getAge());
list.forEach(System.out::println);
}
1.8、@FunctionalInterface注解
这个注解是函数式接口注解,所谓的函数式接口,首先是一个接口,然后就是在这个接口中只能有一个抽象方法
也称为SAM接口,即Single Abstract Method interfaces
特点:
- 接口有且仅有一个抽象方法
- 允许定义静态方法
- 允许定义默认方法
- 允许java.lang.Object中的public方法
- 该注解不是必须的,如果一个接口符合函数式接口定义,name加不加该注解都没有影响,加上该注解能更好的让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionalInterface,那么编译器会报错
实例:
// 正确的函数式接口
@FunctionalInterface
public interface CorrectInterface{
// 抽象方法
public void sub();
// java.lang.Object中的public方法
public boolean equals(Object o);
// 默认方法
public default void defaultMethod(){}
// 静态方法
public static void staticMethod(){}
}
// 错误的函数式接口,有多个抽象方法
// @FunctionalInterface
public interface ErrorInterface{
void add();
void sub();
}
1.9、系统内置函数式接口
在jdk的java.util.funciton包下,有一系列内置函数式接口

浙公网安备 33010602011771号