web-dev-qa-db-ja.com

HashMapをファイルに読み書きする方法は?

次のHashMapがあります。

HashMap<String,Object> fileObj = new HashMap<String,Object>();

ArrayList<String> cols = new ArrayList<String>();  
cols.add("a");  
cols.add("b");  
cols.add("c");  
fileObj.put("mylist",cols);  

次のようにファイルに書き込みます。

File file = new File("temp");  
FileOutputStream f = new FileOutputStream(file);  
ObjectOutputStream s = new ObjectOutputStream(f);          
s.writeObject(fileObj);
s.flush();

次に、このファイルを、オブジェクトがArrayListであるHashMapに読み戻します。私が単に行う場合:

File file = new File("temp");  
FileInputStream f = new FileInputStream(file);  
ObjectInputStream s = new ObjectInputStream(f);  
fileObj = (HashMap<String,Object>)s.readObject();         
s.close();

これは、オブジェクトを保存した形式でオブジェクトを提供しません。15個のnull要素と3番目の要素に<mylist、[a、b、c]>ペアを持つテーブルを返します。そもそも、提供した値を持つ要素を1つだけ返すようにしたいと思います。
//同じオブジェクトをHashMapに読み込むにはどうすればよいですか?

OK Cemのメモに基づいて:これは正しい説明のようです:

ObjectOutputStreamは、オブジェクト(この場合はHashMap)を直列化して、ObjectInputStreamがシリアル化解除できると理解する形式でシリアル化し、Serializableオブジェクトに対して一般的にそうします。必要な形式でシリアル化する場合は、独自のシリアライザを記述する必要があります。 /deserializer.

私の場合:ファイルからオブジェクトを読み取ってデータを取得し、必要なことをすべて実行するときに、HashMap内の各要素を単純に反復処理します。 (データがあるポイントでのみループに入ります)

おかげで、

19
lisam

HashMapの内部表現とHashMapの動作を混同しているようです。コレクションは同じです。ここにそれを証明する簡単なテストがあります。

public static void main(String... args)
                            throws IOException, ClassNotFoundException {
    HashMap<String, Object> fileObj = new HashMap<String, Object>();

    ArrayList<String> cols = new ArrayList<String>();
    cols.add("a");
    cols.add("b");
    cols.add("c");
    fileObj.put("mylist", cols);
    {
        File file = new File("temp");
        FileOutputStream f = new FileOutputStream(file);
        ObjectOutputStream s = new ObjectOutputStream(f);
        s.writeObject(fileObj);
        s.close();
    }
    File file = new File("temp");
    FileInputStream f = new FileInputStream(file);
    ObjectInputStream s = new ObjectInputStream(f);
    HashMap<String, Object> fileObj2 = (HashMap<String, Object>) s.readObject();
    s.close();

    Assert.assertEquals(fileObj.hashCode(), fileObj2.hashCode());
    Assert.assertEquals(fileObj.toString(), fileObj2.toString());
    Assert.assertTrue(fileObj.equals(fileObj2));
}
13
Peter Lawrey

よくある間違いをしていると思います。使用後にストリームを閉じるのを忘れました!

 File file = new File("temp");  
 FileOutputStream f = new FileOutputStream(file);  
 ObjectOutputStream s = new ObjectOutputStream(f);          
 s.writeObject(fileObj);
 s.close();
3
Hbas

jSONファイルを使用してMAPオブジェクトを読み書きすることもできます。

マップオブジェクトをJSONファイルに書き込むには

    ObjectMapper mapper = new ObjectMapper();

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("name", "Suson");
    map.put("age", 26);

    // write JSON to a file
    mapper.writeValue(new File("c:\\myData.json"), map);

JSONファイルからマップオブジェクトを読み取るには

    ObjectMapper mapper = new ObjectMapper();

        // read JSON from a file
        Map<String, Object> map = mapper.readValue(
                new File("c:\\myData.json"),
                new TypeReference<Map<String, Object>>() {
        });

        System.out.println(map.get("name"));
        System.out.println(map.get("age"));

objectMapperをcom.fasterxml.jacksonからインポートし、コードをtry catchブロックに配置します

あなたの最初の行:

HashMap<String,Object> fileObj = new HashMap<String,Object>();

値がSerializableであることが保証されていないため、正しく書き出されない可能性があるため、一時停止しました。実際には、オブジェクトをHashMap<String, Serializable>として定義する必要があります(または、必要に応じて、Map<String, Serializable>を単純化してください)。

また、単純なString -> List<String>マッピングを行うため、JSONなどの単純なテキスト形式でマップをシリアル化することも検討します。

1
aarestad

私はあなたが節約しているものを手に入れていると信じています。保存する前にマップを調べましたか? HashMap内:

_/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 16;
_

例えばデフォルトのHashMapは16 nullsで始まります。バケットの1つを使用するので、保存するとnullsが15個しか残りません。これは、ロードしたときに得られるものです。 fileObj.keySet().entrySet()または.values()を調べて、期待どおりのものを確認してください。

HashMapsは、メモリのトレードオフ中に高速になるように設計されています。詳細は Wikipediaのハッシュテーブル エントリを参照してください。

1
Stephen