如何减少 Java 基于字节的列表对象大小

How to reduce Java List object size based on bytes

我有一个 Java 长字符串列表,我正在使用 net.sourceforge.sizeof.SizeOf 尝试找到大小并将此列表 1 减 1,直到总列表对象大小 <= 50000 字节。我下面的代码性能很糟糕。

    import net.sourceforge.sizeof.SizeOf;

    List<String> mySuperLongStrings;   // this list contains thousands of long strings

    Long size = SizeOf.deepSizeOf(mySuperLongStrings); 

    while (size > Long.valueOf(50000)) {
        if (!mySuperLongStrings.isEmpty()) {
            mySuperLongStrings.remove(0);
            size = SizeOf.deepSizeOf(mySuperLongStrings);
        } 
    }

关于如何做到这一点有什么建议吗?

因为 Size.deepSizeOf(list) 每次都必须迭代整个列表,所以您的算法具有二次运行时复杂度。您可以轻松地将其更改为线性,如果您只是单独总结列表中字符串的大小,一旦超过 50000 字节的限制就停止:

public static <T> List<T> sizedSubList(List<T> list, long maxSize) {
    long totalSize = 0;
    int i = list.size() - 1;
    while (i >= 0) {
        totalSize += SizeOf.deepSizeOf(list.get(i));
        if (totalSize > maxSize) break;
        i--;
    }

    return list.subList(i + 1, list.size());
}

(结果可能略大于maxSize,因为该算法没有考虑列表对象本身的大小——包括内部存储数组)。

用法:

List<String> smallList = sizedSubList(largeList, 50000);

请注意,该方法返回的子列表只是原始列表的一个视图,因此后续对原始列表的修改将反映在子列表中,反之亦然。