Java での私のアプリケーションでは、計算のためにハッシュ テーブルが必要であり、このハッシュ テーブルを何百万回も参照する必要があります。ハッシュ テーブルは、ディスクから HashTable ユーティリティに非常に高速に読み取る必要があり、ハッシュ テーブル内のデータは静的であり、挿入や削除は必要ありません。
そのために利用可能なライブラリを使用することをお勧めしますか?
また、データのサイズは200MB未満です。
人間が読める形式である必要がない場合は、データがSerializableインターフェイスを実装していることを確認し、ObjectOutputStreamを使用してHashMapをシリアル化することに頼ることができます。それは醜いですが、それは仕事を成し遂げるでしょう。
もう1つのオプションは、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のデフォルトエンコーディングを使用することもできます。また、文字列のように長さが可変の場合は、実際のデータを書き込む前に、まずそのデータの長さを書き込む必要があることに注意してください。これは、その文字列を再構築するために読み込む必要のあるバイト数を知ることができるようにするためです。
データが静的である場合、単純な古い配列を使用してインデックスで検索してみませんか? key
使用する意図が何であれ、index
属性を指定するだけです。もちろん、可能な最大配列長を超える場合は、複数の配列に分割する必要があります。
直接のランダムアクセスに勝るハッシュ関数はなく、キーセット(「完全なハッシュ関数」)にインデックスを割り当てるコストは、ルックアップごとではなく、初期化中に前払いされると思います。