Java 8 函数式编程接口
一、函数式接口简介
- 什么是函数式接口
在接口中,有且只有一个抽象方法,那么这个接口就是函数式接口。函数式接口是Lambda表达式使用的前提条件。
- 为什么使用函数式接口
在Java中不支持将函数作为一个数据,也就不能将函数作为方法的参数进行传递。因此给函数外加一层接口的声明,相当于为其穿上一件漂亮的外衣包装起来,如果需要将函数作为方法传递时,就可以传递函数所在接口的实现类对象,来间接的传递方法内容了。
- 函数式接口定义
使用@FunctionalInterface注解来检查一个接口是否是一个函数式接口。放在接口定义的上方,如果接口是函数式接口,编译通过;如果不是,则编译失败。
- 与Lambda表达式的关系
Lambda表达式:函数式接口是Lambda表达式的基础,通过函数式接口可以定义Lambda表达式的参数类型和返回类型。Lambda表达式可以简洁地表示一个函数,可以用于替代匿名内部类的写法,使代码更加简洁和易读。
二、函数式接口案例
通过代码案例进行学习。代码编程提供思路,学习编程思想尤为重要!
- 创建一个带有一个方法的接口
package org.example;
@FunctionalInterface
public interface TestFuncation{
public void fun();
}
- 使用函数式接口运行测试
package org.example;
public class Main {
public static void test(TestFuncation myfun){
myfun.fun();
}
public static void main(String[] args) {
//1.使用匿名内部类的方式
TestFuncation myfun = new TestFuncation() {
@Override
public void fun() {
System.out.println("使用匿名内部类的方式实现函数式接口....");
}
};
test(myfun);
//2.直接传递匿名内部类
test(new TestFuncation() {
@Override
public void fun() {
System.out.println("使用直接传递匿名内部类的方式....");
}
});
//3.使用Lambda表达式的方式使用函数式接口
test(()-> System.out.println("使用Lambda表达式的方式使用函数式接口..."));
}
}
运行结果:
使用匿名内部类的方式实现函数式接口....
使用直接传递匿名内部类的方式....
使用Lambda表达式的方式使用函数式接口...
Process finished with exit code 0
- 进阶使用
使用Java8中提供了一些常用的函数式接口,在使用类似功能的时候,不需要额外定义接口,直接使用jdk8中提供的即可。
接下来直接提供代码样例:
package org.example;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class TestConsumer {
//定义方法实现用户消费的功能
public static void userConsumer(Double money, Consumer<Double> con){
con.accept(money);
}
//测试
public static void main(String[] args) {
//客户1:花了X元, 买了一盒化妆品
userConsumer(500.0,money -> System.out.println("客户1花了"+money+"买了一盒化妆品"));
//客户2:花了X元, 吃了一顿美食
userConsumer(800.0,money -> System.out.println("客户2花了"+money+"元钱吃了一顿美食"));
//1.客户1 : 要5个1-10之间的随机数整数
List<Integer> list1 = useSupplier(5, () -> (int) (Math.random() * 10 + 1));
System.out.println(list1);
//2.客户2 : 要8个1-100之间的偶数
List<Integer> list2 = useSupplier(8, () -> {
int num = (int) (Math.random() * 100 + 1);
if (num % 2 == 0) {
return num;
} else {
return num + 1;
}
});
System.out.println(list2);
// 1)客户1 : y为x的2倍
System.out.println(useFunction(5, x -> x * 2));// 10
// 2) 客户2 : y为x的平方
System.out.println(useFunction(-9, x -> x * x));// 81
}
/*
* 根据客户需求,返回n个满足某个规律的数
* */
public static List<Integer> useSupplier(int count, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
Integer integer = sup.get();
list.add(integer);
}
return list;
}
/*
* 根据x计算y
* 参数x代表用户传递的数
* 参数2代表用户要求得到结果的实现方式
* */
public static int useFunction(int x, Function<Integer, Integer> fun) {
return fun.apply(x);
}
}
执行结果:
客户1花了500.0买了一盒化妆品
客户2花了800.0元钱吃了一顿美食
[2, 9, 3, 10, 6]
[26, 54, 14, 100, 14, 28, 100, 66]
10
81
Process finished with exit code 0
最后,关于编程思想,通过询问GPT回答以下内容:
编程思想是指在软件开发过程中应用的一套理念、原则和方法。下面列举了几种常见的编程思想:
面向对象编程(Object-Oriented Programming, OOP):将问题划分为对象,通过定义对象的属性和方法来实现程序的组织和功能。OOP 基于封装、继承和多态的概念,提倡代码的可重用性、可维护性和可扩展性。
函数式编程(Functional Programming,FP):将计算视为函数的应用,强调使用纯函数来进行编程,避免共享状态和可变数据。函数式编程注重数据的不变性、函数的组合和高阶函数的使用。
响应式编程(Reactive Programming):基于事件流和数据流的概念,将程序建模为一系列的数据变化和事件响应。响应式编程关注数据流的转换和异步操作的处理,使得开发响应式、高效和可伸缩的应用程序更为容易。
结构化编程(Structured Programming):通过顺序、选择和循环等结构化控制流程,以及使用函数和子程序来组织代码。结构化编程强调模块化和可读性,使得程序逻辑更加清晰和易于理解。
领域驱动设计(Domain-Driven Design, DDD):将软件开发过程中的关注重点放在领域模型和业务需求上,通过深入理解领域知识来指导软件系统的设计与实现。DDD 强调建立统一的语言和模型,以及将复杂领域划分为上下文边界。
测试驱动开发(Test-Driven Development, TDD):在编写代码之前先编写测试用例,通过反复编写测试和实现代码的周期来推动开发。TDD 强调编写可测试的、高质量的代码,并倡导在开发过程中进行频繁的自动化测试。
这些编程思想并不是相互排斥的,很多时候可以结合使用,根据实际情况选择合适的思想来解决问题。同时,不同的编程语言和开发环境可能对某些思想有更好的支持,开发者可以根据需要选择适合自己的编程思想。
本文来自博客园,作者:博客-涛,转载请注明原文链接:https://www.cnblogs.com/htmsmile/p/17605673.html