Java学习笔记-day04-函数式编程
2024-01-09 06:54:59
0.Java函数式编程
- 使用
函数式接口
、Lambda表达式
、Stream API
、方法引用
编写的代码即为函数式编程
1.函数式接口
- 只包含一个抽象方法
- 可以有默认方法
- 可以有静态方法
函数式接口(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;
}
}
2.Lambda表达式
- 格式:(参数表) -> {方法体}
- Lambda表达式可简化函数式接口实例的创建
- 该格式实际为映射到函数式接口的抽象方法上
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));
}
3.Stream API
- Stream 是处理集合数据的工具,可以对数据集合进行各种转换、过滤、映射等操作
- 整个流程可以被概括为“创建 -> 中间操作 -> 终端操作”
- 在终端操作执行之前,中间操作是惰性的(通过回调执行),不会立即执行。
- 中间操作的方法参数为
回调函数
- 中甲操作和终端操作的执行顺序是交替执行的
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 未收集到数据
4.方法引用
简化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;
文章来源:https://blog.csdn.net/Demo_00/article/details/135456287
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!