函数式接口在方法形参中的运用
目录
函数式接口在方法形参中的运用
场景
在项目中,需要对接各种各样的算法接口(http)每个算法的大致结构是固定的,但是根据算法类型不同,可能会返回不同的字段属性,运用于业务系统中做判断。在这个时候就需要针对算对应的特殊字段做特殊的处理。为了避免重复解析json,可以将特殊处理的代码块通过函数式接口来代替,在每个算法中去实现相关的解析即可。
前期准备
我通过本地的json文件
来模拟算法接口返回的json
数据
AlarmJson1.json
{
"code": 200,
"data": {
"alarmDetectObjectList1": [
{
"score": 0.9887,
"name": "alarm1",
"box": [[1,0], [1,1], [1,5], [5,0]]
}
]
}
}
AlarmJson2.json
{
"code": 200,
"data": {
"alarmDetectObjectList2": [
{
"score": 0.9881,
"name": "alarm2",
"box": [[0,0], [0,1920], [1080,1920], [1080,0]],
"ext1": 69
}
]
}
}
可以看见,算法1
还是常见的数据结构,但是算法2
多了一个ext1
字段用作特殊业务处理使用
方法封装实现
- 定义算法业务类
package com.example.spring.boot.test.alarm.json;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* @Description
* @Author wuhuaming
* @Date 2023/8/31
*/
@Data
public class AlarmBO implements Serializable {
/**
* 算法名称
*/
private String name;
/**
* 算法检测值
*/
private Double score;
/**
* 算法检测的点位集合
*/
private List<List<Integer>> box;
/**
* 算法额外参数
*/
private Map<String, Object> paramMap;
}
- 定义json解析方法,在形参中采用
BiConsumer<JSONObject, AlarmBO> function
来代替特殊业务逻辑处理,具体实现有方法调用则提供
/**
* 将json结果装配到AlarmBO中
* @param alarmBOList
* @param jsonPath
* @param alarmCode
* @param function
*/
private void getAlarmBOList(List<AlarmBO> alarmBOList, String jsonPath, String alarmCode, BiConsumer<JSONObject, AlarmBO> function){
JSONObject jsonObject = JSONObject.parseObject(this.getJsonString(jsonPath));
if(jsonObject.getInteger("code") == 200){
JSONObject dataJsonObject = jsonObject.getJSONObject("data");
if(dataJsonObject.containsKey(alarmCode)){
JSONArray alarmDetectObjectList = dataJsonObject.getJSONArray(alarmCode);
if(!alarmDetectObjectList.isEmpty()){
for(int i = 0; i< alarmDetectObjectList.size(); i++){
JSONObject item = alarmDetectObjectList.getJSONObject(i);
AlarmBO alarmBO = JSONObject.parseObject(alarmDetectObjectList.getString(i), AlarmBO.class);
function.accept(item, alarmBO);
alarmBOList.add(alarmBO);
}
}
}
}else{
log.error("json parse error{}", jsonObject.get("message"));
}
}
- 调用传参:
// 不需要处理
this.getAlarmBOList(alarmBOList, jsonPath, "alarmDetectObjectList1", (jsonObject, alarmBO)->{});
// 处理特殊字段ext1
this.getAlarmBOList(alarmBOList2, jsonPath2, "alarmDetectObjectList2", (jsonObject, alarmBO)->{
// 将算法2的扩展字段放入map中
if(jsonObject.containsKey("ext1")){
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("ext1", jsonObject.getString("ext1"));
alarmBO.setParamMap(paramMap);
}
});
测试
package com.example.spring.boot.test.alarm.json;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.mysql.cj.log.Log;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
/**
* @Description
* @Author wuhuaming
* @Date 2023/8/31
*/
@Slf4j
public class AlarmJsonTest {
@Test
public void test1(){
List<AlarmBO> alarmBOList = new ArrayList<>();
String jsonPath = "AlarmJson1.json";
this.getAlarmBOList(alarmBOList, jsonPath, "alarmDetectObjectList1", (jsonObject, alarmBO)->{});
System.out.println(alarmBOList);
List<AlarmBO> alarmBOList2 = new ArrayList<>();
String jsonPath2 = "AlarmJson2.json";
this.getAlarmBOList(alarmBOList2, jsonPath2, "alarmDetectObjectList2", (jsonObject, alarmBO)->{
// 将算法2的扩展字段放入map中
if(jsonObject.containsKey("ext1")){
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("ext1", jsonObject.getString("ext1"));
alarmBO.setParamMap(paramMap);
}
});
System.out.println(alarmBOList2);
}
/**
* 将json结果装配到AlarmBO中
* @param alarmBOList
* @param jsonPath
* @param alarmCode
* @param function
*/
private void getAlarmBOList(List<AlarmBO> alarmBOList, String jsonPath, String alarmCode, BiConsumer<JSONObject, AlarmBO> function){
JSONObject jsonObject = JSONObject.parseObject(this.getJsonString(jsonPath));
if(jsonObject.getInteger("code") == 200){
JSONObject dataJsonObject = jsonObject.getJSONObject("data");
if(dataJsonObject.containsKey(alarmCode)){
JSONArray alarmDetectObjectList = dataJsonObject.getJSONArray(alarmCode);
if(!alarmDetectObjectList.isEmpty()){
for(int i = 0; i< alarmDetectObjectList.size(); i++){
JSONObject item = alarmDetectObjectList.getJSONObject(i);
AlarmBO alarmBO = JSONObject.parseObject(alarmDetectObjectList.getString(i), AlarmBO.class);
function.accept(item, alarmBO);
alarmBOList.add(alarmBO);
}
}
}
}else{
log.error("json parse error{}", jsonObject.get("message"));
}
}
/**
* 读取json文件
* @param jsonPath
* @return
*/
private String getJsonString(String jsonPath) {
String basePath = System.getProperty("user.dir") + "/src/main/resources/static/" + jsonPath;
BufferedReader bufferedReader = null;
String len = null;
StringBuilder de = new StringBuilder();
try {
bufferedReader = new BufferedReader(new FileReader(basePath));
while ((len = bufferedReader.readLine()) != null) {
de.append(len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return de.toString();
}
}
结果:
[AlarmBO(name=alarm1, score=0.9887, box=[[1, 0], [1, 1], [1, 5], [5, 0]], paramMap=null)]
[AlarmBO(name=alarm2, score=0.9881, box=[[0, 0], [0, 1920], [1080, 1920], [1080, 0]], paramMap={ext1=69})]
Process finished with exit code 0