lisam
lisam

Reputation: 199

How to read and write a HashMap to a file?

I have the following 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);  

I write it to a file as follows:

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

Now I want to read this file back to a HashMap where the Object is an ArrayList. If i simply do:

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

This does not give me the object in the format that I saved it in. It returns a table with 15 null elements and the < mylist,[a,b,c] > pair at the 3rd element. I want it to return only one element with the values I had provided to it in the first place.
//How can I read the same object back into a HashMap ?

OK So based on Cem's note: This is what seems to be the correct explanation:

ObjectOutputStream serializes the objects (HashMap in this case) in whatever format that ObjectInputStream will understand to deserialize and does so generically for any Serializable object. If you want it to serialize in the format that you desire you should write your own serializer/deserializer.

In my case: I simply iterate through each of those elements in the HashMap when I read the Object back from the file and get the data and do whatever I want with it. (it enters the loop only at the point where there is data).

Thanks,

Upvotes: 19

Views: 81640

Answers (6)

Nithesh Gowda
Nithesh Gowda

Reputation: 19

Same data if you want to write to a text file

public void writeToFile(Map<String, List<String>> failureMessage){
    if(file!=null){
        try{
           BufferedWriter writer=new BufferedWriter(new FileWriter(file, true));
            for (Map.Entry<String, List<String>> map : failureMessage.entrySet()) {
                writer.write(map.getKey()+"\n");
                for(String message:map.getValue()){
                    writer.write(message+"\n");
                }
                writer.write("\n");
            }
            writer.close();
        }catch (Exception e){
            System.out.println("Unable to write to file: "+file.getPath());
            e.printStackTrace();
        }
    }
}

Upvotes: 0

Surendranath Sonawane
Surendranath Sonawane

Reputation: 1737

you can also use JSON file to read and write MAP object.

To write map object into JSON file

    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);

To read map object from JSON file

    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"));

and import ObjectMapper from com.fasterxml.jackson and put code in try catch block

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533492

You appear to be confusing the internal resprentation of a HashMap with how the HashMap behaves. The collections are the same. Here is a simple test to prove it to you.

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));
}

Upvotes: 14

Hbas
Hbas

Reputation: 904

I believe you´re making a common mistake. You forgot to close the stream after using it!

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

Upvotes: 3

Stephen
Stephen

Reputation: 19944

I believe you're getting what you're saving. Have you inspected the map before you save it? In HashMap:

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

e.g. the default HashMap will start off with 16 nulls. You use one of the buckets, so you only have 15 nulls left when you save, which is what you get when you load. Try inspecting fileObj.keySet(), .entrySet() or .values() to see what you expect.

HashMaps are designed to be fast while trading off memory. See Wikipedia's Hash table entry for more details.

Upvotes: 1

aarestad
aarestad

Reputation: 607

Your first line:

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

gave me pause, as the values are not guaranteed to be Serializable and thus may not be written out correctly. You should really define the object as a HashMap<String, Serializable> (or if you prefer, simpy Map<String, Serializable>).

I would also consider serializing the Map in a simple text format such as JSON since you are doing a simple String -> List<String> mapping.

Upvotes: 1

Related Questions