У меня есть следующий 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, где Объектом является 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]> пара в 3-м элементе. Я хочу, чтобы это возвратило только один элемент со значениями, которые я предоставил ему во-первых.
//Как я могу считать тот же объект назад в HashMap?
Хорошо Так на основе примечания Cem: Это - то, что, кажется, корректное объяснение:
ObjectOutputStream сериализирует объекты (HashMap в этом случае) в любом формате, который ObjectInputStream поймет для десериализации и делает так в общем для любого сериализуемого объекта. Если Вы хотите, чтобы это сериализировало в формате, что Вы требуете, чтобы Вы записали свой собственный serializer/deserializer.
В моем случае: Я просто выполняю итерации через каждый из тех элементов в HashMap, когда я считал Объект назад из файла и получаю данные и делаю то, что я хочу с ним. (это вводит цикл только в точке, где существуют данные).
Спасибо,
Ваша первая строка:
HashMap<String,Object> fileObj = new HashMap<String,Object>();
заставила меня задуматься, поскольку не гарантируется, что значения будут Serializable
и, следовательно, могут быть записаны неправильно. Вы действительно должны определить объект как HashMap
(или, если хотите, simpy Map
).
Я бы также рассмотрел возможность сериализации карты в простом текстовом формате, таком как JSON, поскольку вы выполняете простое отображение String -> List
.
Я считаю, что вы получаете то, что экономите. Вы проверили карту, прежде чем сохранить ее? В HashMap
:
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 16;
,например, HashMap
по умолчанию будет начинаться с 16 null
s. Вы используете одну из корзин, поэтому при сохранении у вас остается только 15 null
s, что вы и получаете при загрузке.
Попробуйте проверить fileObj.keySet()
, .entrySet()
или .values()
, чтобы увидеть, что вы ожидаете.
HashMap
предназначены для быстрой торговли памятью. Для получения более подробной информации см. Запись о хэш-таблице Википедии.
Я считаю, что вы делаете частую ошибку. Вы забыли закрыть поток после его использования!
File file = new File("temp");
FileOutputStream f = new FileOutputStream(file);
ObjectOutputStream s = new ObjectOutputStream(f);
s.writeObject(fileObj);
s.close();
Похоже, вы путаете внутреннее воспроизведение 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));
}