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