日常开发中使用的函数式接口

简介: 使用了java8,必不可少的好朋友-函数式接口

1. 四大核心函数式接口

1.1 Consumer

消费型接口,有T类型的入参,无反参

voidaccept(Tt);

1.2 Supplier

供给型接口,无入参,有T类型的反参

Tget();

1.3 Function

函数式接口,有T类型的入参,有R类型的反参

Rapply(Tt);

1.4 Predicate

断言型接口,有T类型的入参,有boolean类型的反参

booleantest(Tt);

2. 其他函数接口

2.1 BiConsumer

两个入参的消费型接口,T,U

voidaccept(Tt, Uu);

2.2 BiFunction

两个入参的函数式接口,入参T,U,反参R

Rapply(Tt, Uu);

2.3 UnaryOperator

对参数类型T进行操作,入参T,反参T,为Function的子接口

@FunctionalInterfacepublicinterfaceUnaryOperator<T>extendsFunction<T, T> {
static<T>UnaryOperator<T>identity() {
returnt->t;
    }
}

3. 实际应用

3.1 痛点

使用EasyExcel进行excel进行导入

EasyExcel的 读操作 需要实现 ReadListener 接口以及定义一个映射 T 泛型存储数据行的实体。


如:示例中的 DemoDataListenerDemoData

publicclassDemoDataListenerimplementsReadListener<DemoData> {
// 省略具体的方法实现}


由于每次导入都要写一个Listener,非常麻烦,就想有没有一个能减少劳动力的方法呢?


3.2 实现解决

就利用了消费型接口 Consumer<T>去做了实现

3.2.1 实现ReadListener,这里实现的是抽象类AnalysisEventListener,也是一个ReadListener
publicclassEasyExcelConsumerListener<T>extendsAnalysisEventListener<T> {
privatefinalList<T>list;
privatefinalConsumer<List<T>>consumer;
publicEasyExcelConsumerListener(Consumer<List<T>>consumer){
this.consumer=consumer;
list=newArrayList<>();
    }
@Overridepublicvoidinvoke(Tdata, AnalysisContextcontext) {
list.add(data);
    }
@OverridepublicvoiddoAfterAllAnalysed(AnalysisContextcontext) {
consumer.accept(list);
    }
}
3.2.2 扩展EasyExcel
publicclassEasyExcelUtilextendsEasyExcel {
privateEasyExcelUtil() {
    }
publicstatic<T>ExcelReaderBuilderread(InputStreaminputStream, Class<T>head, Consumer<List<T>>consumer) {
returnread(inputStream, head, newEasyExcelConsumerListener<>(consumer));
    }
}    
3.2.3 使用

Controller 层的代码实现,其中 ExcelData.class 是需要映射的数据实体类,这个映射实体类好像不能投机取巧了~~~

@RestContoller@RequestMapping("/excel")
publicclassExcelController {
@AutowiredprivateIExcelServiceservice;
@GetMapping("/importExcel")
publicRimportExcel(MultipartFilefile) throwsIOException {
// service层执行具体的importExcel方法实现EasyExcelUtil.read(file.getInputStream(), ExcelData.class, service::importExcel).sheet().doRead();
returnR.success("导入成功!");
    }
}

这样就可以关注具体的业务实现啦


3.2.4 使用两个参数的 BiConsumer<T, U>,与上面的 Consumer<T> 异曲同工

实现 Listener

/*** 异步导入* 由于获取不到当前登录用户,通过参数传进来*/publicclassAsyncBiConsumerListener<T>extendsAnalysisEventListener<T> {
privatefinalLonguserId;
privatefinalList<T>list;
privatefinalBiConsumer<List<T>, Long>biConsumer;
publicAsyncBiConsumerListener(BiConsumer<List<T>, Long>biConsumer, LonguserId){
this.userId=userId;
this.biConsumer=biConsumer;
list=newArrayList<>();
    }
@Overridepublicvoidinvoke(Tdata, AnalysisContextcontext) {
list.add(data);
    }
@OverridepublicvoiddoAfterAllAnalysed(AnalysisContextcontext) {
biConsumer.accept(list, userId);
    }
}

扩展 EasyExcel

publicclassEasyExcelUtilextendsEasyExcel {
privateEasyExcelUtil() {
    }
publicstatic<T>ExcelReaderBuilderread(InputStreaminputStream, Class<T>head, Consumer<List<T>>consumer) {
returnread(inputStream, head, newEasyExcelConsumerListener<>(consumer));
    }
publicstatic<T>ExcelReaderBuilderread(InputStreaminputStream, Class<T>head, BiConsumer<List<T>, Long>biConsumer, LonguserId) {
returnread(inputStream, head, newAsyncBiConsumerListener<>(biConsumer, userId));
    }
}

使用

publicvoidimportExcel(InputStreamfile, Stringkey, LonguserId) {
try {
EasyExcelUtil.read(file, ExcelData.class, service::importExcel, userId).sheet().doRead();
    } catch (Exceptionex) {
log.error("异步导入异常:", ex);
    }
}
目录
相关文章
|
算法 数据安全/隐私保护
【算法练习】IDEA集成leetcode插件实现快速刷题
【算法练习】IDEA集成leetcode插件实现快速刷题
2311 0
【算法练习】IDEA集成leetcode插件实现快速刷题
|
8月前
|
人工智能 运维 监控
AI Agent 职业路线全景解析:体系化构建开发者职业竞争力
本文基于阿里云开发者社区视角,系统梳理AI Agent五大职业路径:技术研发、产品方案、运营优化、交叉治理及核心能力构建,涵盖技术栈、场景适配、数据迭代、合规治理等关键维度,为开发者提供可落地的职业发展指南。(239字)
619 2
|
4月前
|
人工智能 运维 开发工具
一篇搞懂 AI Agent 架构选型,避开 80% 落地坑!
AI Agent正加速落地,但架构选型常成绊脚石。本文精析LangChain、LangGraph、AutoGen、CrewAI、OpenAI Agents SDK五大主流框架,从任务复杂度、可控性、开发效率、成本四大维度对比,助企业按需选型、避坑提速,实现智能化升级。
一篇搞懂 AI Agent 架构选型,避开 80% 落地坑!
|
6月前
|
算法 Java Sentinel
高可用架构核心:限流熔断降级全解,Sentinel 与 Resilience4j 原理 + 落地实战
本文深入解析分布式系统高可用三大核心手段——限流、熔断、降级的本质与边界,对比剖析Sentinel(全链路流量治理)与Resilience4j(轻量函数式容错)的底层原理、实战配置及选型策略,并提供生产环境最佳实践与避坑指南。
976 1
|
8月前
|
人工智能 API 人机交互
AI Agent 职业路线全解析:从入门到专家的能力构建与进阶指南
本文系统解析AI Agent开发者成长路径:从“模型中心”转向“系统中心”,涵盖认知架构、记忆管理、工具集成与多Agent协作四大核心技术;提出“应用落地→架构设计→领域专家”三阶进阶路线;揭示其在人机交互变革、工程溢价与技术边界拓展中的长期价值。(239字)
1023 1
|
XML Java 数据库连接
优雅的参数校验,告别冗余if-else
本文介绍了在 Java Spring Boot 开发中如何使用 JSR 303 和 Hibernate Validator 进行参数校验,以避免冗余的if-else判断。文章涵盖了基本注解的使用、全局异常处理、分组校验、嵌套对象校验、快速失败配置以及自定义校验规则等实用技巧。
629 10
优雅的参数校验,告别冗余if-else
TortoiseSVN使用-合并分支代码
TortoiseSVN使用-合并分支代码
2841 1
|
消息中间件 存储 监控
RabbitMQ 队列之战:Classic 和 Quorum 的性能洞察
RabbitMQ 是一个功能强大的消息代理,用于分布式应用程序间的通信。它通过队列临时存储消息,支持异步通信和解耦。经典队列适合高吞吐量和低延迟场景,而仲裁队列则提供高可用性和容错能力,适用于关键任务系统。选择哪种队列取决于性能、持久性和容错性的需求。
1311 6
|
消息中间件 缓存 NoSQL
Redis stream 用做消息队列完美吗
Redis Stream 是 Redis 5.0 版本中引入的一种新的数据结构,它用于实现简单但功能强大的消息传递模式。 这篇文章,我们聊聊 Redis Stream 基本用法 ,以及如何在 SpringBoot 项目中应用 Redis Stream 。
Redis stream 用做消息队列完美吗
|
easyexcel Java 测试技术
Alibaba EasyExcel
Alibaba EasyExcel
1162 1