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的子接口
publicinterfaceUnaryOperator<T>extendsFunction<T, T> { static<T>UnaryOperator<T>identity() { returnt->t; } }
3. 实际应用
3.1 痛点
使用EasyExcel进行excel进行导入
EasyExcel的 读操作 需要实现 ReadListener
接口以及定义一个映射 T
泛型存储数据行的实体。
如:示例中的 DemoDataListener
和 DemoData
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<>(); } publicvoidinvoke(Tdata, AnalysisContextcontext) { list.add(data); } publicvoiddoAfterAllAnalysed(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
是需要映射的数据实体类,这个映射实体类好像不能投机取巧了~~~
"/excel") (publicclassExcelController { privateIExcelServiceservice; "/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<>(); } publicvoidinvoke(Tdata, AnalysisContextcontext) { list.add(data); } publicvoiddoAfterAllAnalysed(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); } }