0

我在 Java 中的应用程序需要一个哈希表来进行计算,并且它必须对这个哈希表进行数百万次查找。哈希表必须可以非常快速地从磁盘读取到 HashTable 实用程序中,并且 hast 表中的数据是静态的,不需要插入或删除。

您是否建议使用任何可用的库来这样做?

此外,数据的大小小于 200MB。

4

2 回答 2

1

如果您的数据是静态的,为什么不使用普通的旧数组并按索引查找呢?无论key您打算使用什么,只需提供一个index属性。当然,如果超过了可能的最大数组长度,则需要跨多个数组进行分片。

我想说没有哈希函数可以击败直接随机访问,并且在初始化期间而不是每次查找时,为您的密钥集(您的“完美哈希函数”)分配索引的成本将是预先的。

于 2012-07-10T01:52:47.070 回答
1

如果人类可读性不是必需的,那么您可以只需要确保您的数据实现 Serializable 接口并使用 ObjectOutputStream 序列化 HashMap 即可。这很丑陋,但它可以完成工作。

另一种选择是 DataInputStream 和 DataOutputStream。这些允许您读/写结构化的二进制数据。

假设你有一个 HashMap,你可以这样写:

// realOutputStream should probably be a BufferedOutputStream
DataOutputStream output = new DataOutputStream( realOutputStream );
for (Map.Entry<Long, String> entry : map.entrySet()) {
    // Write the key
    output.writeLong(entry.getKey().longValue());
    byte bytes[] = entry.getBytes("UTF-8");
    // Writing the string requires writing the length and then the bytes
    output.writeInt(bytes.length);
    output.write(bytes, 0, bytes.length);
}



// realInputStream should probably be a BufferedInputStream
DataInputStream input = new DataInputStream ( realInputStream );
Map<Long, String> map = new HashMap<Long, String>();
while ( true ) {
   try {
     // read the key
     long key = output.readLong();
     // read the string length in bytes
     int strlen = output.readInt();
     // read the bytes into an array
     byte buf[] = new byte[strlen];
     output.readFully(buf, 0, strlen);
     // Create the map entry.
     map.put(Long.valueOf(key), new String(buf,"UTF-8"));
   }
   catch (EOFException e) {
     // input is exhausted
     break;
   }
}

请记住,这是假设您要将字符串存储和读取为 UTF。您可以轻松地不提供字符集并使用 jvm 默认编码。另请注意,具有可变长度的东西(如字符串)将要求您在写入实际数据之前先写入该数据的长度。这样您就可以知道需要读取多少字节才能重建该字符串。

于 2012-07-10T02:54:15.260 回答