如何将HashMap读写到文件中?

19
我有以下的 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?

好的,根据Cem的说明:这是正确的解释:

ObjectOutputStream将对象(在本例中为HashMap)序列化为任何ObjectInputStream将理解的格式,并且对于任何可序列化对象,都会进行通用序列化。如果要将其序列化为所需的格式,则应编写自己的序列化器/反序列化器。

在我的情况下:当我从文件中读回对象并获取数据并执行所需操作时,我仅迭代HashMap中的每个元素(它仅在存在数据的点进入循环)。

谢谢,


1
“不以我保存的格式提供对象”是什么意思?请提供一些您所看到和期望的示例。 - Jim Garrison
3
为什么你的HashMap没有声明为HashMap<String,List<String>> - Jim Garrison
它返回一个包含15个空元素和< mylist,[a,b,c] >对在第3个元素的表格。我希望它只返回一个元素,并且该元素具有我最初提供给它的值。 - lisam
看,ObjectOutputStream会将对象(在本例中为HashMap)序列化为任何格式,以便ObjectInputStream可以通用地进行反序列化。如果您希望以所需格式进行序列化,则应编写自己的序列化器/反序列化器。 - Cem Catikkas
3
15个空元素的键是什么?fileObj.size()的结果是什么? - Istao
显示剩余3条评论
6个回答

14

你似乎混淆了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));
}

3
我相信您犯了一个常见的错误。 在使用完流之后,您忘记关闭它!
 File file = new File("temp");  
 FileOutputStream f = new FileOutputStream(file);  
 ObjectOutputStream s = new ObjectOutputStream(f);          
 s.writeObject(fileObj);
 s.close();

不是的。我已经关闭了流,只是在代码中没有提到而已。我现在已经进行了修改。 - lisam
1
无论如何,f.close() 都不能正确关闭 ObjectOutputStream。您应该始终在最顶层的修饰流上调用 close,即 s.close() - BalusC

2

您也可以使用JSON文件来读写MAP对象。

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

从com.fasterxml.jackson导入ObjectMapper,并将代码放在try catch块中。


请参考此链接:https://www.mkyong.com/java/how-to-convert-java-map-to-from-json-jackson/,了解如何将Java Map转换为JSON(Jackson)。 - Surendranath Sonawane

1

你的第一行:

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

这让我停下来思考,因为这些值不能保证是可序列化的,因此可能无法正确写出。你应该将对象定义为HashMap<String, Serializable>(或者如果你愿意,简单地使用Map<String, Serializable>)。

我还会考虑使用像JSON这样的简单文本格式对Map进行序列化,因为你正在做一个简单的字符串 -> List<String>映射。


这些代码所在的类本身是可序列化的。 - lisam

1

我相信你保存的是你想要的。在保存之前,你有检查过这个地图吗?在HashMap中:

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

例如,默认的HashMap将以16个null开始。当您保存时,您使用其中一个桶,因此只剩下15个null,这就是您加载时得到的结果。 尝试检查fileObj.keySet().entrySet().values()以查看您期望的内容。

HashMap旨在在权衡内存的同时保持快速性能。有关更多详细信息,请参见Wikipedia的哈希表条目。


0

如果你想要将相同的数据写入文本文件中

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接