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

Java中如何将ArrayList<Integer>转为字节数组再转成BLOB?

Java 中 ArrayList 转压缩BLOB存储数据库指南

核心思路

直接将数值序列化为字节数组(无需Base64,因为Base64会增加约33%的体积,不符合压缩存储的需求),然后用GZIP压缩,最后写入数据库BLOB字段;读取时反向操作即可。

步骤1:将 ArrayList 中的数值转为字节数组

处理 Integer 类型

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public static byte[] intListToBytes(ArrayList<Integer> intList) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    // 先写入元素个数,方便还原时读取
    dos.writeInt(intList.size());
    for (Integer num : intList) {
        dos.writeInt(num);
    }
    dos.close();
    return baos.toByteArray();
}

处理 Double 类型

public static byte[] doubleListToBytes(ArrayList<Double> doubleList) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    dos.writeInt(doubleList.size());
    for (Double num : doubleList) {
        dos.writeDouble(num);
    }
    dos.close();
    return baos.toByteArray();
}

混合类型处理(同时有Integer和Double)

可以先写入类型标记,再写入对应数值:

public static byte[] mixedListToBytes(ArrayList<Number> mixedList) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    dos.writeInt(mixedList.size());
    for (Number num : mixedList) {
        if (num instanceof Integer) {
            dos.writeByte(0); // 标记为Integer
            dos.writeInt(num.intValue());
        } else if (num instanceof Double) {
            dos.writeByte(1); // 标记为Double
            dos.writeDouble(num.doubleValue());
        }
        // 可扩展其他数值类型
    }
    dos.close();
    return baos.toByteArray();
}

步骤2:压缩字节数组

使用GZIP压缩减少体积:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public static byte[] compress(byte[] data) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
    gzipOut.write(data);
    gzipOut.close();
    return baos.toByteArray();
}

// 对应的解压方法
public static byte[] decompress(byte[] compressedData) throws IOException {
    ByteArrayInputStream bais = new ByteArrayInputStream(compressedData);
    GZIPInputStream gzipIn = new GZIPInputStream(bais);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len;
    while ((len = gzipIn.read(buffer)) != -1) {
        baos.write(buffer, 0, len);
    }
    gzipIn.close();
    return baos.toByteArray();
}

步骤3:存入数据库BLOB字段

JDBC操作示例:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public static void saveBlobToDb(Connection conn, byte[] compressedData, int monthId) throws SQLException {
    String sql = "INSERT INTO monthly_weather_stats (month_id, stats_blob) VALUES (?, ?)";
    try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        pstmt.setInt(1, monthId);
        pstmt.setBytes(2, compressedData);
        pstmt.executeUpdate();
    }
}

步骤4:从BLOB读取并还原数据

以还原Integer列表为例:

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

public static ArrayList<Integer> readIntListFromDb(Connection conn, int monthId) throws Exception {
    String sql = "SELECT stats_blob FROM monthly_weather_stats WHERE month_id = ?";
    ArrayList<Integer> intList = new ArrayList<>();
    try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        pstmt.setInt(1, monthId);
        try (ResultSet rs = pstmt.executeQuery()) {
            if (rs.next()) {
                byte[] compressedData = rs.getBytes("stats_blob");
                byte[] rawData = decompress(compressedData);
                DataInputStream dis = new DataInputStream(new ByteArrayInputStream(rawData));
                int size = dis.readInt();
                for (int i = 0; i < size; i++) {
                    intList.add(dis.readInt());
                }
                dis.close();
            }
        }
    }
    return intList;
}

关键注意事项

  • 避免Base64编码:Base64会将二进制转为文本,额外增加体积,BLOB字段直接存储字节数组即可。
  • 序列化一致性:还原数据时必须和序列化时的顺序、类型严格对应,否则会出现数据错误。
  • 异常处理:IO操作和数据库操作需妥善捕获异常,防止数据损坏或丢失。
  • 性能考量:日常气象月度数据量不大,无需分块处理;若数据量极大,可考虑分块存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:07:07