Как читать и писать 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();

Теперь я хочу прочитать этот файл обратно в HashMap, где Object является ArrayList. Если я просто делаю:

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

Это не дает мне объект в том формате, в котором я его сохранил. Он возвращает таблицу с 15 нулевыми элементами и < mylist, [a, b, c] > на третьем элементе. Я хочу, чтобы он возвращал только один элемент со значениями, которые я ему предоставил в первую очередь.
  // Как я могу прочитать один и тот же объект в HashMap?

OK Итак, основываясь на примечании Cem: Это то, что кажется правильным объяснением:

ObjectOutputStream сериализует объекты (в этом случае HashMap) в любом формате, который ObjectInputStream будет понимать для десериализации и делает это в общем случае для любого объекта Serializable. Если вы хотите, чтобы он сериализовался в желаемом формате, вы должны написать собственный сериализатор/десериализатор.

В моем случае: я просто перебираю каждый из этих элементов в HashMap, когда я читаю объект обратно из файла и получаю данные и делаю все, что захочу. (он входит в цикл только в том месте, где есть данные).

Спасибо,

Ответы

Ответ 1

Кажется, вы вводите в заблуждение внутреннюю репатриацию 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));
}

Ответ 2

Я считаю, что вы делаете распространенную ошибку. Вы забыли закрыть поток после его использования!

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

Ответ 3

Ваша первая строка:

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

дал мне паузу, так как значения не гарантируются Serializable и, следовательно, могут быть неправильно записаны. Вы должны действительно определить объект как HashMap<String, Serializable> (или, если хотите, simpy Map<String, Serializable>).

Я бы также рассмотрел сериализацию карты в простом текстовом формате, таком как JSON, так как вы делаете простое сопоставление String -> List<String>.

Ответ 4

Я считаю, что вы получаете то, что вы спасете. Вы проверили карту, прежде чем ее сохранить? В HashMap:

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

например. по умолчанию HashMap начнется с 16 null s. Вы используете один из ведер, поэтому при сохранении осталось только 15 null, что вы получаете при загрузке. Попробуйте проверить fileObj.keySet(), .entrySet() или .values(), чтобы узнать, чего вы ожидаете.

HashMap предназначены для быстрой работы при обмене памяти. Подробнее см. запись в Wikipedia Hash table.

Ответ 5

вы также можете использовать 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 и поместите код в блок catch catch