• ベストアンサー

HashMapに最初からデータをセットする

検索キーがUnicode一文字ぐらい、Valueが多くて20バイトぐらいの検索キー->Valueの一方行の変換をやろうと思っています。レコードの数は、6000~10000個ぐらいのオーダーです。レコードの追加・更新はきわめて稀で、辞書のようなイメージです(というか、漢字の辞書です)。 「これぐらいのオーダーなら、多くて数百KBだからメモリに全部読み込めるだろう」という推論をしました。さらに、数百KBなら、外部から辞書ファイルを読み込むこともできるが、クラスファイル内にデータを定数として埋め込むこともできるのでは?と考えました。そこで、クラス内にこのデータをハッシュの形で埋め込む方法を考えたのですが、 HashMap hashmap=new HashMap(); hashmap.put("key","value"); とやれば、ハッシュにデータが追加されますよね?ただ、これの方法をとるとすると、結局数千個のレコードについて、hashmap.putという命令を行うという無駄なことをやることになります。クラスファイル内にデータを埋め込むのであれば、Javaがクラスを読んだ時点ですでに変数が使えるようにする方法が原理的にはあると思うのですが、コードが思いつきません。 たとえば、このhashmapという変数を何かファイルに書き出して、実行時にロードしてやればhashmapという変数がそのまま使える、というようなことはできないのでしょうか?何かいいアイデアがありましたら、お教えください。

質問者が選んだベストアンサー

  • ベストアンサー
  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.5

>と読めたのですが・・・何か間違っている気がします。 私の認識も同じですよ。 シリアライズで出力したファイルは、元のクラスに変更があると、読めなくなりました。 (回避方法があるのかもしれませんが、私は知りません) この変更というのは、フィールドの追加・削除だけでなく、再コンパイルしただけでも変更と認識される気がしました。 ところで、ファイルに出力するなら、わざわざこんな事をしなくても、普通にCSV等のファイルに書いてもいいのではないでしょうか? それにこの方法は、 >Javaがクラスを読んだ時点ですでに変数が使えるようにする という条件にはならないと思いますけど。 ファイルに書かないのなら、やはり#2の方法かと思いますね。

betagamma
質問者

お礼

お礼が遅くなりまして、大変申し訳ありません。 >ところで、ファイルに出力するなら、わざわざこんな事をしなくても、普通にCSV等のファイルに書いてもいいのではないでしょうか? シリアライズの部分などが、nativeコードで書いてあれば、CSVを読むより早いかなぁ?と思ったりもするのですが・・・あんまり関係ありませんよね。 JAVAの中から一つ一つCSVのデータを拾っていくのは、遅いかなぁ、と思ったもので。nativeコードで書かれている部分を使って、うまくできないかなぁ?と思ったのですが、そこまでして高速化する必要もないかな、と思い始めました。

その他の回答 (4)

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.4

#2です。 hashmapをファイルに書き出すのが目的なのかな? でしたら、他の方が言っているように、直列化すればいいのですが、 個人的には、 java.beans.XMLEncoder java.beans.XMLDecoder を使うことをお勧めします。

betagamma
質問者

お礼

二回も回答して頂いてありがとうございます。

betagamma
質問者

補足

>hashmapをファイルに書き出すのが目的なのかな? そうです。それが直接的な目的ではないですが、それができれば問題ありません。 >java.beans.XMLEncoder >java.beans.XMLDecoder こちらのほうも拝見いたしました。こちらは、XMLで書き出されるのですようですが、直列化との違いはなんでしょうか?自分がドキュメントを読んだところでは、 「直列化は、環境・VMのバージョンに依存するが、XMLEncoder/XMLDecoderは依存しない」と読めたのですが・・・何か間違っている気がします。できれば、ファイルに書き出したファイルをjarの中に一緒にいれて、それをプログラムから読み込めばよいようにしたいので、VMや環境に依存しないようにしたいのですが・・・

  • shige_70
  • ベストアンサー率17% (168/946)
回答No.3

直列化(Serialize)という手法を使うことで実現できます。 これが可能なクラスはSerializableインタフェースを実装しています。幸い、HashMapクラスはこの条件を満たしています。 まず、作成するアプリケーションとは別に、そのHashMapにデータをつっこんでファイルに書き出すプログラムを書いてください。書き出すには、java.io.ObjectOutputStreamクラスのwriteObject()メソッドを使います。 上記のプログラムを実行し、HashMapのデータファイルを作成します。 作成するアプリケーションでは、java.io.ObjectInputStreamクラスのreadObject()を使ってそのファイルを読み込みます。

betagamma
質問者

お礼

ありがとうございます! >直列化(Serialize)という手法を使うことで実現できます。 こういう機能(変数をファイルに書き出す->後で読み込む)は、Serializeというのですね。Javaのことだから、そのくらいの機能はあるだろう、と予想はしていましたが、具体的な手法や名称は知りませんでした。 staticなbyte型の配列でハッシュデータを用意して、自分でハッシュのプログラムも書かないのといけないのか?とか考えているところでした。この方法でも理論的にはできますが、めんどくさいですし、ローカルなプログラムになってしまうので悩んでいました。ありがとうございました。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

ちょっと意味がわからないのですが、 class Test { final public static String A= "DPOKPSFKG"; final public static String B= "AOJFVDLVV"; final public static String C= "SDEVMDV+D"; final public static String D= "SD?@?FPLM"; . . . のように定義しておくということでしょうか? スタティックイニシャライザーの中で、リフレクションを使ってみたら、うまくいきそうな気がしますけど。

回答No.1

>たとえば、このhashmapという変数を何かファイルに>書き出して、実行時にロードしてやればhashmapとい>う変数がそのまま使える、 Serializableインターフェースはどうでしょう。

関連するQ&A