0

我正在用java编写一个程序。我的密钥是可写的,值是位串 0,1。位串的大小可能是 1,000,000(由 0 或 1 组成)。我必须使用什么类型的数据占用最少的空间?谢谢。

4

1 回答 1

2

您可以使用 ajava.util.BitSet将您的位打包成 long,从而接收某种压缩。在您提到的 1024 位的情况下,您可以使用 1024/64=16 个长字节对数据进行编码,它占用 8 个字节,因此总共只使用 128 个字节。

要实现 aWritable你必须实现相同的调用接口:

public class BitSetWritable implements Writable {

  private BitSet set;

  public BitSetWritable() {
    // default constructor
  }

  public BitSetWritable(BitSet set) {
    this.set = set;
  }
  [...]
}

我在这里添加了一些方便的构造函数,注意默认构造是 Hadoop 序列化机制的必备。

实现接口后,你不得不实现两个方法:readFieldswrite

 @Override
  public void write(DataOutput out) throws IOException {
    long[] longs = set.toLongArray();
    out.writeInt(longs.length);
    for (int i = 0; i < longs.length; i++) {
      out.writeLong(longs[i]);
    }
  }

  @Override
  public void readFields(DataInput in) throws IOException {
    long[] longs = new long[in.readInt()];
    for (int i = 0; i < longs.length; i++) {
      longs[i] = in.readLong();
    }

    set = BitSet.valueOf(longs);
  }

这很简单,您写入集合中分配的 long 的数量(只有 4 个字节的开销),然后写入 bitset 的 long 值。回读时,你倒着做同样的事情。

如果您想直接复制,我已将完整文件和测试用例添加到我在 github 上的库中:

https://github.com/thomasjungblut/thomasjungblut-common/blob/master/src/de/jungblut/writable/BitSetWritable.java

https://github.com/thomasjungblut/thomasjungblut-common/blob/master/test/de/jungblut/writable/BitSetWritableTest.java

于 2013-08-23T16:50:41.103 回答