函数式接口在方法形参中的运用

函数式接口在方法形参中的运用

场景

在项目中,需要对接各种各样的算法接口(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
0%