函数式编程(JAVA)——@FunctionalInterface
概述
只有一个抽象方法的接口我们称之为函数接口。这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。
特点
- 接口有且仅有一个抽象方法。
- 允许定义静态方法。
- 允许定义默认方法。
- 允许java.lang.Object中的public方法。
- 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
下述所有测试代码源码地址:https://gitee.com/ArnoldSu/functionalProgramming.git
自定义函数式接口
package com.bestarnold.www;
/**
* CustomFunctionalInterface 自定义函数式接口
*
* @author Arnold 409196007@qq.com
* @version V2.0
* @date 2022/06/14 12:12
**/
@FunctionalInterface
public interface CustomFunctionalInterface<T> {
/**
* description 抽象方法
*
* @param t 泛型对象
* @return void
* @author Arnold
* @date 2022/6/14
**/
void println(T t);
/**
* description 静态方法打印
*
* @param str 待打印字符串
* @return void
* @author Arnold
* @date 2022/6/14
**/
static void print(String str) {
System.out.print(str);
}
/**
* description 默认方法按照给定次数打印
*
* @param str 打印字符串
* @param times 打印次数
* @return void
* @author Arnold
* @date 2022/6/14
**/
default void printForTimes(String str, Integer times) {
for (int i = 0; i < times; i++) {
System.out.println(str);
}
}
/**
* description java.lang.Object中的public方法
*
* @param obj 比对对象
* @return boolean
* @author Arnold
* @date 2022/6/14
**/
boolean equals(Object obj);
}
自定义函数式接口测试
/**
* description 自定义函数式接口测试使用
*
* @param
* @return void
* @author Arnold
* @date 2022/6/14
**/
@Test
public void customFunctionalInterfaceTest() {
//抽象方法
CustomFunctionalInterface<User> customFunctionalInterface =
(User user) -> System.out.println(user.getName());
initUsers.stream().forEach(customFunctionalInterface::println);
//默认方法打印
customFunctionalInterface.printForTimes("默认方法打印字符串", 3);
//静态方法打印
CustomFunctionalInterface.print("静态方法打印字符串");
//继承
System.out.println();
System.out.println(customFunctionalInterface.equals(customFunctionalInterface));
}
JDK常见函数式接口
Supplier
代表结果的提供者(生产者)。不要求每次调用供应商时都返回新的或不同的结果。这是一个功能接口,其功能方法是get() 。
/**
* description supplier 测试
*
* @param
* @return void
* @author Arnold
* @date 2022/6/14
**/
@Test
public void supplierTest() {
Supplier<Date> dateSupplier = Date::new;
System.out.println(dateSupplier.get());
}
Consumer
表示接受单个输入参数且不返回结果的操作。与大多数其他功能接口不同, Consumer预计将通过副作用进行操作(消费者),其功能方法是accept(Object) 。
/**
* description Consumer 测试
*
* @param
* @return void
* @author Arnold
* @date 2022/6/14
**/
@Test
public void consumerTest() {
initUsers.stream().forEach(new Consumer<User>() {
@Override
public void accept(User user) {
System.out.println(user.getName());
}
});
System.out.println("=============lambda 形式===============");
initUsers.stream().forEach(user -> System.out.println(user.getName()));
}
Predicate
表示一个参数的谓词(布尔值函数)。这是一个功能接口,其功能方法是test(Object)。
/**
* description Predicate 复合条件防范
*
* @param list 待判断数据
* @param predicate1 判断条件1
* @param predicate2 判断条件2
* @return void
* @author Arnold
* @date 2022/6/15
**/
public static void conditionFilter(List<User> list, Predicate<User> predicate1, Predicate<User> predicate2) {
list.forEach((user) -> {
if (predicate1.and(predicate2).test(user)) {
System.out.println(user);
}
});
}
/**
* description Predicate 测试
*
* @param
* @return void
* @author Arnold
* @date 2022/6/14
**/
@Test
public void predicateTest() {
Boolean flag = initUsers.stream().anyMatch(new Predicate<User>() {
@Override
public boolean test(User user) {
return user.getAge() > 88;
}
});
System.out.println("年龄大于88的人");
System.out.println(flag);
System.out.println("=============lambda 形式===============");
Boolean flag1 = initUsers.stream().anyMatch(user -> user.getAge() > 88);
System.out.println("年龄大于88的人");
System.out.println(flag1);
System.out.println("=============Predicate 复合条件(年龄大于88并且事男性的人员信息)===============");
//Predicate 复合条件(年龄大于88并且事男性的人员信息)
conditionFilter(initUsers, user -> user.getAge() > 88, user -> user.getSex() == 1);
}
Function
表示接受一个参数并产生结果的函数。其功能方法是apply(Object) 。
/**
* description Function 测试
*
* @param
* @return void
* @author Arnold
* @date 2022/6/14
**/
@Test
public void functionTest() {
List<Optional<List<Department>>> oldManList = initUsers.stream().map(new Function<User, Optional<List<Department>>>() {
@Override
public Optional<List<Department>> apply(User user) {
return user.getSex() == 1 ? Optional.ofNullable(user.getDep()) : Optional.empty();
}
}).collect(Collectors.toList());
oldManList.forEach((optional) -> optional.ifPresent(departments -> System.out.println(departments)));
System.out.println("=============lambda 形式===============");
List<Optional<List<Department>>> oldManList1 = initUsers.stream().map((Function<User, Optional<List<Department>>>) user
-> user.getSex() == 1 ? Optional.ofNullable(user.getDep()) : Optional.empty()).collect(Collectors.toList());
oldManList1.forEach((optional) -> optional.ifPresent(departments -> System.out.println(departments)));
System.out.println("=============Function 复合条件(年龄加十岁昵称加一个前缀Function)===============");
//Predicate 复合条件(年龄大于88并且事男性的人员信息)
initUsers.stream().limit(1).map(new Function<User, User>() {
@Override
public User apply(User user) {
return user.setAge(user.getAge() + 10);
}
}.compose(new Function<User, User>() {
@Override
public User apply(User user) {
return user.setNickName("Function" + user.getNickName());
}
})).collect(Collectors.toList()).forEach(user -> System.out.println(user));
}