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

简介: 使用了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);
    }
}
目录
相关文章
|
5月前
|
并行计算 Java API
深入理解Java中的Lambda表达式与函数式接口
【7月更文挑战第19天】在Java 8中引入的Lambda表达式,不仅简化了代码编写,还为函数式编程提供了支持。本文将探讨Lambda表达式的核心概念、其与函数式接口的关系以及如何在Java中高效利用这一特性来提升代码的简洁性和可读性。我们将通过实例分析Lambda表达式的语法规则和常见用法,同时解释函数式接口的设计原则及其在Java标准库中的应用,旨在帮助开发者更好地理解和运用这一强大的工具。
|
4月前
|
Java 开发者
Java 8新特性之Lambda表达式与函数式接口
【7月更文挑战第59天】本文将介绍Java 8中的一个重要新特性——Lambda表达式,以及与之密切相关的函数式接口。通过对比传统的匿名内部类,我们将探讨Lambda表达式的语法、使用方法和优势。同时,我们还将了解函数式接口的定义和用途,以及如何将Lambda表达式应用于函数式编程。
|
7月前
|
Java API
Java的Lambda表达式与函数式接口的技术性文章
Java的Lambda表达式与函数式接口的技术性文章
30 0
|
7月前
|
Java
匿名内部类&Lambda表达式&函数式接口
匿名内部类&Lambda表达式&函数式接口
38 0
|
Java 编译器 索引
3.4 函数式接口与Lambda表达式的实际应用:编写更灵活和通用的代码
3.4 函数式接口与Lambda表达式的实际应用:编写更灵活和通用的代码
48 0
|
Java API Scala
【JDK新特性】一篇搞懂Lambda表达式 & 函数式接口
【JDK新特性】一篇搞懂Lambda表达式 & 函数式接口
|
并行计算 Java 编译器
【javaSE】 Lambda表达式与Lambda表达式的使用
【javaSE】 Lambda表达式与Lambda表达式的使用
|
Java
教你如何封装自定义函数式接口
前言 Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包,和传统数学上的意义有区别。【摘自百度百科】
172 0
|
Java 编译器
函数式接口
函数式接口
|
Java 编译器
1.2 Lambda表达式的基础:Lambda表达式的函数式接口
1.2 Lambda表达式的基础:Lambda表达式的函数式接口
67 0