我有一个长字符串的Java列表,我正在使用net.sourceforge.sizeof.SizeOf
来尝试查找大小并逐个减少此列表,直到List对象的总大小为< = 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);
}
}
有关如何做到这一点的任何建议?
答案 0 :(得分:1)
因为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);
请注意,此方法返回的子列表只是原始列表的视图,因此原始列表的后续修改将反映在子列表中,反之亦然。