函数式接口
、Lambda表达式
、Stream API
、方法引用
编写的代码即为函数式编程函数式接口(Functional Interface)是指仅包含一个抽象方法的接口。函数式接口是Java中支持函数式编程的关键概念之一。函数式编程强调的是将计算视为数学函数的求值,并避免程序状态的改变。Java 8引入了Lambda表达式和函数式接口的概念,以更方便地支持函数式编程。
函数式接口具有以下特点:
- 只包含一个抽象方法: 函数式接口只能包含一个抽象方法。这个抽象方法定义了接口的行为,而其他非抽象方法可以有多个。
- 可以有默认方法: 除了唯一的抽象方法外,函数式接口可以包含多个默认方法。默认方法在接口中已经有默认的实现,但仍然可以被子类覆盖。
- 可以有静态方法: 函数式接口还可以包含静态方法。这些方法在接口级别上是静态的,不依赖于接口的实例。
@FunctionalInterface //加上该注解,若接口不符合函数式接口的定义,编译器会产生错误
interface MyInterface {
//抽象方法
int sum(int i, int j);
//静态方法
default int defaultSum(int i, int j){
return i + j;
}
//默认方法
static int staticSum(int i, int j){
return i + j;
}
}
public static void main(String[] args) {
//2.MyInterface的实现类实例,通过匿名内部类创建
MyInterface myInterface = new MyInterface() {
@Override
public int sum(int i, int j) {
return i+j+1;
}
};
//2.Lambda表达式简化函数式接口实例的创建
//格式:(参数表) -> {方法体}
//该格式实际为映射到函数式接口的抽象方法 sum()
MyInterface myInterfaceLambda = (i, j) ->{
return i+j+1;
} ;
System.out.println("myInterface.sum(3,4) = " + myInterface.sum(3, 4));
System.out.println("myInterfaceLambda.sum(3,4) = " + myInterfaceLambda.sum(3, 4));
}
回调函数
public static void main(String[] args) {
List<String> myList = Arrays.asList("5555", "1", "333", "22", "4444");
myList.stream()
.filter(s -> {
System.out.println("filter s = " + s); //【回调函数】
if (s.length() < 3) {
System.out.println("filter 收集到数据了");
} else {
System.out.println("filter 没有收集到数据了");
}
return s.length() < 3;
})
.map((Function<String, Object>) s -> {
System.out.println("map s = " + s); //【回调函数】
return s.toUpperCase();
})
.forEach(s -> {
System.out.println("forEach s = " + s); //【回调函数】
});
}
Stream流中大量使用是函数式接口作为方法参数,因此,Lambda表达式在Stream流中大量使用
输出结果:
filter s = 5555
filter 未收集到数据
filter s = 1
filter 收集到数据了!!!
map s = 1
forEach s = 1
filter s = 333
filter 未收集到数据
filter s = 22
filter 收集到数据了!!!
map s = 22
forEach s = 22
filter s = 4444
filter 未收集到数据
简化Lambda表达式的编写,那么实质也是一个函数式接口
方法引用种类
//静态方法引用: 引用类的静态方法
//格式:类名::静态方法
// Lambda表达式
Function<Integer, String> lambdaStatic = x -> Long.toString(x);
// 静态方法引用
Function<Integer, String> referenceStatic = Long::toString;
//实例方法引用: 引用特定对象的实例方法
//格式:实例::成员方法
//和类方法引用的区别:目前来看,一个是无参函数,一个是有参函数。
//实例方法引用应该很少用,多此一举的操作。可以直接用实例调用该方法就获取到结果,所以实例方法引用结果也是固定的,
// Lambda表达式
String str = "Hello";
Supplier<Object> lambdaInstance = () -> str.toUpperCase();
// 实例方法引用
Supplier<String> referenceInstance = str::toUpperCase;
//类方法引用:引用类的成员方法
//格式:类名::成员方法
// Lambda表达式
Function<String, String> lambdaClass = s -> s.toUpperCase();
// 类方法引用
Function<String, String> referenceClass = String::toUpperCase;
//构造方法引用: 引用类的构造方法。
// Lambda表达式
Supplier<List<String>> lambdaStructure = () -> new ArrayList<>();
// 构造方法引用
Supplier<List<String>> referenceStructure = ArrayList::new;