我在 Java 中的应用程序需要一个哈希表来进行计算,并且它必须对这个哈希表进行数百万次查找。哈希表必须可以非常快速地从磁盘读取到 HashTable 实用程序中,并且 hast 表中的数据是静态的,不需要插入或删除。
您是否建议使用任何可用的库来这样做?
此外,数据的大小小于 200MB。
如果您的数据是静态的,为什么不使用普通的旧数组并按索引查找呢?无论key
您打算使用什么,只需提供一个index
属性。当然,如果超过了可能的最大数组长度,则需要跨多个数组进行分片。
我想说没有哈希函数可以击败直接随机访问,并且在初始化期间而不是每次查找时,为您的密钥集(您的“完美哈希函数”)分配索引的成本将是预先的。
如果人类可读性不是必需的,那么您可以只需要确保您的数据实现 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 默认编码。另请注意,具有可变长度的东西(如字符串)将要求您在写入实际数据之前先写入该数据的长度。这样您就可以知道需要读取多少字节才能重建该字符串。