目录
一、导言
二、函数式接口的定义和特点
I. 什么是函数式接口
II. 函数式接口的特点和约束
III. Lambda表达式和函数式接口的关系
三、Java中常用的函数式接口
I. java.util.function包下的常用函数式接口
Predicate:判断传入的对象是否满足某个条件
Function:将传入的对象映射为另一个对象,>
Consumer:对传入的对象执行某个操作
Supplier:生成一个对象
II. 自定义函数式接口
MyFunction:接收一个类型为T的参数,返回一个类型为R的结果,>
四、使用函数式接口的代码示例
函数式编程是一种强调函数组合和纯函数的编程范式,它基于λ演算和数学中的函数式和集合论。在Java中,函数式接口为函数式编程提供了强大的支持,它们作为Lambda表达式的目标类型,简化了代码编写并提高了可读性。函数式编程和函数式接口在Java中的引入,为我们带来了更灵活和简洁的编程方式。
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
Lambda表达式和函数式接口的关系可以简单总结为:Lambda表达式是实现函数式接口的一种方式。
接口声明
// 该接口的特点:有参数、有返回值、且返回值类型为boolean类型。
@FunctionalInterface
public interface Predicate {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
}
代码示例演示
public class PredicateFunction {
public static void main(String[] args) {
// Predicate 通常用于条件的判断
// 需求: 判断姓名是否合法(姓名长度小于3合法)
predicateTest(new Predicate() { // 使用匿名内部类创建对象,并实现Predicate接口
@Override
public boolean test(String s) { // 重写Predicate接口中的test方法
return s.length() > 3; //指定判定规则
}
});
}
/**
* 检查姓名长度是否超过三个字符
* @param predicate 谓词
*/
public static void predicateTest(Predicate predicate) {
boolean result = predicate.test("迪丽热巴"); //调用test方法,注意此时被调用的test方法已被重写
System.out.println(result ? "名字太长了" : "名字合法");
}
}
接口声明
// 该接口的特点:有参数、有返回值。
@FunctionalInterface
public interface Function {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
代码示例演示
public class FunctionInterface {
public static void main(String[] args) {
// Function能够将参数由一种类型转成另一种类型,通常用于不同对象之间的映射转换
// 需求:将String类型转为Integer类型
functionTest(new Function() { // 使用匿名内部类创建创建对象,并实现Function接口
@Override
public Integer apply(String s) { // 重写Function接口中的apply方法
return Integer.valueOf(s);
}
});
}
/**
* 将字符串转为数字
* @param function 函数参数
*/
public static void functionTest(Function function){
Integer number = function.apply("1234"); //调用Function接口中的apply方法
System.out.println(number); // 输出结果
}
}
接口声明
// 该接口的特点:有参数、无返回值
@FunctionalInterface
public interface Consumer {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
代码示例演示
public class ConsumerFunction {
public static void main(String[] args) {
// 该接口一般用于数组或集合的遍历输出
consumerTest(new Consumer() { // 使用匿名内部类创建创建对象,并实现Consumer接口
@Override
public void accept(String str) {
//将字符串转为小写
System.out.println(str.toLowerCase());
//将字符串转为大写
System.out.println(str.toUpperCase(Locale.ROOT));
}
});
}
/**
* 一个字符串转成大写和小写的字符串
* @param consumer 输入的参数
*/
public static void consumerTest(Consumer consumer){
String str="Hello World!";
consumer.accept(str);
}
}
接口声明
// 该接口的特点:无参数、有返回值
@FunctionalInterface
public interface Supplier {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
代码示例演示
public class SupplierFunction {
public static void main(String[] args) {
supplierTest(new Supplier() { // 使用匿名内部类创建对象,并实现Supplier接口
@Override
public Integer get() { // 重写Supplier接口中的get方法
int[] arrays = new int[]{1, 3, 6, 5, 9, 2, 110, 78, 67};
Arrays.sort(arrays);
return arrays[arrays.length - 1];
}
});
}
/**
* 获取数组元素最大值
* @param supplier 提供者
*/
public static void supplierTest(Supplier supplier){
Integer max = supplier.get();
System.out.println(max);
}
}
T
的参数,返回一个类型为R
的结果接口声明
@FunctionalInterface
interface MyFunction {
R apply(T t);
}
代码示例演示
public class Main {
public static void main(String[] args) {
MyFunction square = num -> num * num;
int result = square.apply(5); // 调用apply方法计算5的平方
System.out.println(result); // 输出25
}
}
1. 使用Predicate函数式接口筛选集合元素
public class Main {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 使用Predicate接口筛选偶数
Predicate evenPredicate = num -> num % 2 == 0;
List evenNumbers = filter(numbers, evenPredicate);
System.out.println("偶数集合:" + evenNumbers);
// 使用Predicate接口筛选大于5的数
Predicate greaterThanFivePredicate = num -> num > 5;
List greaterThanFiveNumbers = filter(numbers, greaterThanFivePredicate);
System.out.println("大于5的数集合:" + greaterThanFiveNumbers);
}
// 筛选集合元素的通用方法
public static List filter(List list, Predicate predicate) {
List filteredList = new ArrayList<>();
for (T item : list) {
if (predicate.test(item)) {
filteredList.add(item);
}
}
return filteredList;
}
}
2. 使用Function函数式接口进行数据转换和映射
public class Main {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5);
// 使用Function接口将每个数乘以2
Function multiplyByTwoFunction = num -> num * 2;
List multipliedNumbers = map(numbers, multiplyByTwoFunction);
System.out.println("每个数乘以2:" + multipliedNumbers);
// 使用Function接口将每个数转换成字符串
Function toStringFunction = num -> String.valueOf(num);
List stringNumbers = map(numbers, toStringFunction);
System.out.println("每个数转换成字符串:" + stringNumbers);
}
// 数据转换和映射的通用方法
public static List map(List list, Function function) {
List resultList = new ArrayList<>();
for (T item : list) {
R result = function.apply(item);
resultList.add(result);
}
return resultList;
}
}
3. 使用Consumer函数式接口对集合进行操作
public class Main {
public static void main(String[] args) {
List numbers = Arrays.asList(1, 2, 3, 4, 5);
// 使用Consumer接口打印每个数
Consumer printNumberConsumer = num -> System.out.println(num);
forEach(numbers, printNumberConsumer);
// 使用Consumer接口将每个数乘以2并打印
Consumer multiplyByTwoConsumer = num -> System.out.println(num * 2);
forEach(numbers, multiplyByTwoConsumer);
}
// 集合操作的通用方法
public static void forEach(List list, Consumer consumer) {
for (T item : list) {
consumer.accept(item);
}
}
}