【问题标题】:HashMap Deserialization Issues in AndroidAndroid中的HashMap反序列化问题
【发布时间】:2012-05-24 09:52:02
【问题描述】:

我正在使用以下代码在我的 PC 应用程序上序列化一个 HashMap:

private void serialize(HashMap<Integer, Integer> map2write, String name_ser)
{// serializes fphlist into .ser file called name_ser
    FileOutputStream fileOut = null;
    try {
        fileOut = new FileOutputStream(project_dir + "/" + name_ser + ".ser");
    } catch (FileNotFoundException ex) {
        Logger.getLogger(AdminConsoleUI.class.getName()).log(Level.SEVERE, null, ex);
    }
    ObjectOutputStream out;
    try {
        out = new ObjectOutputStream(fileOut);
        out.writeObject(map2write);
        out.reset();
        out.flush();
        out.close();
        fileOut.close();

    } catch (IOException ex) {
        Logger.getLogger(AdminConsoleUI.class.getName()).log(Level.SEVERE, null, ex);
    }
}

然后我在我的 Android 应用程序中使用以下代码对其进行反序列化:

private HashMap<Integer,Integer> deserialize_Map(String fn)
{// deserializes fn into HashMap

    HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
    try
    {
        FileInputStream fileIn = new FileInputStream(project_dir + "/" + fn + ".ser");
        ObjectInputStream in = new ObjectInputStream(fileIn);
        hm = (HashMap<Integer,Integer>) in.readObject();
        in.close();
        fileIn.close();

   }catch(IOException i)
   {
       Log.e("MYAPP", "exception", i);
       return null;
   }catch(ClassNotFoundException c)
   {
       Log.e("MYAPP", "exception", c);
       return null;
   }catch(ClassCastException ex)
   {
       Log.e("MYAPP", "exception", ex);
       return null;
   }

    return hm;
}

最后,我面临两个问题。

1) 反序列化需要很长时间。它包含大约数千个键,所以这正常吗?有没有更有效的序列化方法来解决这个问题?

2) 反序列化后,我得到一个 hashmap,其占用的大小几乎是它在 VM 上最初占用的大小的两倍,当我在调试器中检查它时,它最初应该包含的键值之间有很多空条目。但是,它们不是空键,而只是空键,我无法查看其中的内容。我在 Eclipse 中调试。为什么会这样?

【问题讨论】:

    标签: java android serialization hashmap


    【解决方案1】:

    1) VM 大小中“正常”HashMap 的大小是多少? 我不认为这是解决该问题的另一种解决方案(如果有请有人告诉我们)。 您可以尝试共享一个 sqlite 或其他东西。如果您想合作解决您要解决的问题,我们可以提出使工作更快的技术

    更新

    您可以尝试按照您的建议在初始化时初始化您的地图,如果您知道大小HashMap&lt;Integer,Integer&gt; hm = new HashMap&lt;Integer,Integer&gt;(SIZE*2);

    对于2.来自here

    HashMap 的实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的桶数,初始容量只是哈希表创建时的容量。负载因子是哈希表在其容量自动增加之前允许达到的程度的度量。当哈希表中的条目数超过负载因子与当前容量的乘积时,通过调用rehash方法,容量大致翻倍

    【讨论】:

    • 谢谢,这真的很有帮助。我从来不知道我可以使用 HashMap 参数。在初始化期间指定负载因子和容量会有所帮助。
    • 我想知道,我是否可以在反序列化之前创建一个 HashMap 并让 readObject 方法使用该特定的 HashMap 进行写入。你有什么想法吗?
    • 尝试加载一个大的hashMap,这样你就保留了HashMap myMap = new HashMap(numberOfElements * 2);之前的空间。如果这不成功,您可以尝试使用 LinkedHashMap。如果我没记错的话,我也遇到了一些问题,并且 LinkedHashMap 反序列化在 android 中更快(没有任何意义,但我的时间安排很可靠)。你也可以试试
    【解决方案2】:

    您是否尝试过将 HashMap 序列化为 JSON 对象? Android 对从文件中反序列化 JSON 有很好的支持。

    【讨论】:

    • 谢谢。它看起来是标准序列化的一个不错的替代方案。如果用weakwire的解决方案不成功我会考虑的。
    猜你喜欢
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-25
    相关资源
    最近更新 更多