2012-07-10 73 views
0

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

你是否建议使用任何可用的lib来做到这一点?

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

+0

什么是你正在读/写文件的要求?它需要是人类可读的吗? – Matt 2012-07-10 01:46:58

回答

1

如果不需要人类可读性,那么可以通过gasp来确保数据实现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默认编码。还要注意,用的东西像一个字符串变量长度会要求你先写实际数据之前写数据的长度。这样你就可以知道需要读入多少字节才能重建该字符串。

1

如果您的数据是静态的,为什么不使用普通的旧数组并通过索引查找?无论您打算使用哪种key,只需提供一个index属性。当然,如果你超过maximum possible array length,你需要在多个阵列上分割。

我说没有哈希函数可以打败直接随机存取和对您的按键分配指标(你的“完美散列函数”)的成本将前面,在初始化过程中,而不是对每个查询。