压缩java中的整数数组

时间:2009-07-03 22:46:34

标签: java compression

我有一些非常大的整数数组,我想压缩它们 然而,在java中这样做的方法是使用这样的东西 -

int[] myIntArray;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new DeflaterOutputStream(byteArrayOutputStream));
objectOutputStream.writeObject(myIntArray);

请注意,首先需要通过java将int数组转换为字节。 现在我知道这很快但它仍然需要创建一个全新的字节数组并扫描整个原始int数组,将其转换为字节并将值复制到新的字节数组。

有没有办法跳过字节转换并立即压缩整数?

6 个答案:

答案 0 :(得分:4)

跳过ObjectOutputStream,直接将int直接存储为四个byte。例如,DataOutputStream.writeInt是一种简单的方法。

答案 1 :(得分:2)

嗯。除非存在大量冗余,否则通用压缩算法不一定能很好地压缩二进制值数组。根据您对数据的了解,您可能会更好地开发自己的东西。

你实际上试图压缩是什么?

答案 2 :(得分:2)

您可以使用representation使用的Protocol Buffers。每个整数由1-5个字节表示,具体取决于其大小。

此外,新的“打包”表示意味着您基本上可以获得一个“标题”来说明它有多大(以及它在哪个字段中)然后只是数据。这可能是ObjectOutputStream所做的,但它是PB最近的一项创新:)

请注意,这将根据幅度进行压缩, not 根据整数的频率进行压缩。这将极大地影响它是否对你有用。

答案 3 :(得分:0)

字节数组不会为你节省太多内存,除非你把它作为一个包含无符号整数的字节数组,这在Java中是非常危险的。它将用额外的处理时间替换内存开销,以便对代码进行步骤检查。对于数据存储而言,这可能是正确的,但已经存在数据存储解决方案 除非你为了序列化目的这样做,否则我认为你在浪费你的时间。

答案 4 :(得分:0)

如果保证int的数组没有重复项,则可以改为使用java.util.BitSet。

由于它的基本实现是一个位数组,每个位指示BitSet中是否存在某个整数,因此其内存使用率非常低,因此需要较少的空间来序列化。

答案 5 :(得分:0)

在您的示例中,您将压缩流写入ByteArrayOutputStream。您的压缩数组需要存在于某处,如果目标是内存,则可能选择ByteArrayOutputStream。您还可以将流写入套接字或文件。在这种情况下,您不会在内存中复制流。如果您的阵列是800MB并且运行速度为1GB,则可以使用您包含的示例轻松地将阵列写入压缩文件。更改将使用文件流替换ByteArrayOutputStream。

ObjectOutputStream格式实际上非常有效。它不会在内存中复制您的数组,并且具有有效编写数组的特殊代码。

想要在内存中使用压缩数组吗?你的数据是否适合稀疏阵列?当数据中存在较大间隙时,稀疏数组很好。