You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中基于JHDF5实现HDF5工具类的List分支逻辑问题

问题解决:JHDF5工具类中List分支的实现逻辑

问题背景

前端传入的JSON存为文件后,Python读取时会把数字识别成字符串,转换过程存在性能问题,所以计划在Spring Boot中用JHDF5创建HDF5文件。已经实现了HDF5FileUtil工具类,但不知道如何处理List分支的逻辑,需要支持Map嵌套List再嵌套Map的复杂结构。

解决方案

核心思路是根据List中元素的类型分情况处理:

  • 若元素是基础类型(Integer/Double/String),直接转成对应数组写入HDF5数据集
  • 若元素是复杂类型(Map或嵌套List),则把每个元素作为子节点,用索引作为节点名称(比如key4/0/、key4/1/)递归处理

以下是补全后的完整工具类代码:

@Component
public class HDF5FileUtil {

    public void createFile(Map<String, Object> data, String filePath) throws Exception {
        IHDF5Writer writer = null;
        try {
            writer = HDF5Factory.open(filePath);
            writeData(writer, "/", data);
        } catch (Exception e) {
            throw e;
        } finally {
            if (writer != null)
                writer.close();
        }
    }
    
    private void writeData(IHDF5Writer writer, String path, Object data) throws Exception {
        try {
            if(data instanceof Map) {
                for (Map.Entry<String, Object> entry : ((Map<String, Object>) data).entrySet()) {
                    writeData(writer, path + entry.getKey() + "/", entry.getValue());
                }
            } else if(data instanceof List) {
                List<?> list = (List<?>) data;
                if (list.isEmpty()) {
                    return; // 空列表直接跳过,也可根据需求自定义处理
                }
                
                Object firstElement = list.get(0);
                // 处理基础类型列表
                if (firstElement instanceof Integer) {
                    int[] intArray = list.stream().mapToInt(Integer.class::cast).toArray();
                    writer.writeIntArray(path, intArray);
                } else if (firstElement instanceof Double) {
                    double[] doubleArray = list.stream().mapToDouble(Double.class::cast).toArray();
                    writer.writeDoubleArray(path, doubleArray);
                } else if (firstElement instanceof String) {
                    String[] strArray = list.toArray(new String[0]);
                    writer.writeStringArray(path, strArray);
                } 
                // 处理嵌套的复杂类型(Map或List)
                else if (firstElement instanceof Map || firstElement instanceof List) {
                    for (int i = 0; i < list.size(); i++) {
                        writeData(writer, path + i + "/", list.get(i));
                    }
                } 
                // 处理未知类型,可根据需求扩展
                else {
                    throw new IllegalArgumentException("不支持的列表元素类型:" + firstElement.getClass().getName());
                }
            } else if (data instanceof Integer) {
                writer.writeInt(path, (Integer) data);
            } else if (data instanceof Double) {
                writer.writeDouble(path, (Double) data);
            } else if (data instanceof String) {
                writer.writeString(path, (String) data);
            }
            // 可根据需求添加其他基础类型的支持,比如Long、Boolean等
        } catch (Exception e) {
            throw new RuntimeException("写入HDF5数据失败,路径:" + path, e);
        }
    }
}

代码说明

  1. 基础类型列表处理:利用Stream将List转成对应类型的数组,调用JHDF5的writeXXXArray方法写入,这样能保证HDF5数据集的类型一致性,读取时无需额外类型转换。
  2. 复杂类型列表处理:遍历List中的每个元素,以索引作为子节点名称(如key4/0/),递归调用writeData方法处理,完美适配Map嵌套List再嵌套Map的场景。
  3. 异常处理优化:添加了路径信息到异常中,便于快速定位问题;同时对未知类型抛出明确的异常,方便后续扩展支持更多类型。

适配示例JSON

对于你提供的示例JSON,处理后HDF5的节点结构会是这样:

  • /key1:整数1
  • /key2/key2_1:整数数组[1,2,3,4,5]
  • /key2/ket2_2:字符串"Test"
  • /key3:浮点数数组[1.5,3.14,1.23456]
  • /key4/0/key4_1:整数0
  • /key4/0/key4_2:字符串"00"
  • /key4/0/key4_3:二维浮点数数组
  • /key4/1/key4_1:整数1
  • ...以此类推

内容的提问来源于stack exchange,提问作者limsrs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:12:42