2009-11-04 80 views
0

我有一个Java哈希表序列化中的问题,这对我来说似乎不合逻辑,但我无法找到我正在使用的逻辑中的错误。下面是我在做什么,Java哈希表和序列化

Hashtable sspsrpData = new Hashtable(); 
for(int i=0;i<Constants.secondayStructures.length;i++) { 
    SecondaryStructures ss = (SecondaryStructures)(data.get(Constants.secondayStructures[i])); 
    sspsrpData.put(Constants.secondayStructures[i], new SecStrucPSRP(ss.getSecStruct(),ss.getLengthCounts())); 
} 
    FileOutputStream fos = null; 
    ObjectOutputStream out = null; 
    fos = new FileOutputStream(Constants.sspsrpData); 
    out = new ObjectOutputStream(fos); 
    out.writeObject(sspsrpData); 

这段代码应该把3键 - 值对的哈希表,也应该序列由此形成的哈希表。现在,当我试图通过这一段代码以检索他们回来在另一个程序:

FileInputStream fis = null; 
ObjectInputStream in = null; 
fis = new FileInputStream(Constants.sspsrpData); 
in = new ObjectInputStream(fis); 
ssPsrp = (Hashtable)in.readObject(); 

产生的哈希表只有2个键 - 值对。虽然哈希表中的计数表示3我只能在哈希表中看到2个键值对。我不明白什么是错的!

有人可以指出我哪里错了吗?

感谢和美好的一天, Santhosh

+0

您提到的其他程序:是否使用相同的Java版本和完全相同的代码? – sfussenegger 2009-11-04 07:26:25

+0

嗨..是的,其他程序试图反序列化第一个程序序列化的内容。当我查看对象序列化程序时,有3个对象,但是当我查看反序列化程序时,它只包含2个对象,虽然count说是3 .. – user202385 2009-11-04 07:44:00

+0

任何特定的地方,我需要看看.. ?? – user202385 2009-11-04 07:45:07

回答

0

是..奇怪的全部3键值对是相同的(串 - SecStrucPSRP对象)。所有的对象都是可序列化的。其中只有2个是可访问的,而反序列化哈希表..

1

也许Constants.secondayStructures[0] .equals(Constants.secondayStructures[1])Constants.secondayStructures[1] .equals(Constants.secondayStructures[2])

尝试sspsrpData.size()之前序列化你的对象,以确保其具有良好的尺寸以前序列化。

+0

我也这么认为,并开始调试..没有找到一个解决方案,但一个有趣的观察..其中一个关键是添加键时被替换,所以如果最初的哈希表有10个值要填补,第一个加法是在6和下一个加入是在4最后加入是在4再次加入..我不知道这是怎么回事。钥匙是肯定不同的。我试图使用hashmap而不是哈希表,它工作得很好.. Thnaks的答复..如果有人面临同样的问题,我想知道他们是否有相同的调试症状.. – user202385 2009-11-04 08:52:42

+0

这是正常的,几个不同的密钥得到存储在同一位置,该位置由散列函数确定。当几个键被存储在相同的位置时,条目(键+值)被链接。为了得到一个给定值的值,将密钥散列以查找要查看的位置,然后将密钥与等于(在给定位置处的密钥)进行比较。所以hashcode和equals必须是一致的,并且随着时间的推移也会保持稳定... – pgras 2009-11-04 12:15:09

1

HashMap使用“开放哈希”。这意味着,如果插入两个不同的项目,其hashCode方法会生成相同的唯一编号(有时会发生这种情况),则散列表只需将两个条目插入到链接列表的相同位置即可解决此冲突。在调试模式下查看哈希表中的一个条目:还有一个名为“next”的属性。这是一个指向哈希表中相同位置的其他条目的指针。换句话说:HashMap实现管理表中每个位置的“链接列表”。如果一个或多个条目存储在相同的位置(如果它们的hashCode方法计算相同的值),则有关散列表位置将所有这些条目存储在链接列表中。

哈希表序列化的问题是哈希表将内部项存储在不同的位置。在序列化之前,有关项目确实有不同的表格位置。反序列化后,您不能再次找到这些项目,因为它们现在存储在不同的位置。我不知道这是Sun/Oracle的意图。这是一个错误吗?我有同样的问题。我正在寻找任何解决方案。

+0

我找到了我的错:HashMap/Hashtables的序列化以及从反序列化版本的地图提取等效条目效果很好。但是我的地图中的关键对象覆盖了hashCode方法。而这个实现是错误的。看看:[链接](http://www.devx.com/tips/Tip/12934)。如果您面临的问题是无法从反序列化哈希映射中获得相同的关键对象,那么您应该检查您的关键对象的hashCode实现。 – 2011-04-02 19:35:35

0

它是序列化主题中非常重要的一点。散列表中的存储键/值对的哈希表,这是条目所在的位置。水桶位置本身由钥匙的hashCode()制成。所以,现在,如果密钥是一个hashCode()函数没有被覆盖的对象(即;它使用Object.hashCode()),那么这个hashcode值的生成可能不同于JVM到JVM,甚至从一个程序运行到另一个。几乎可以肯定的是,当它反序列化时,它不是同一个对象,而是该实例的一个新参考,它可能导致不同的hashCode()然后在它被序列化时,从而导致流损坏或仅仅找不到对象。您可以执行此操作或为密钥提供原始数据类型。因此,整数可以是一个关键,你可以使用Hashtable.put(2, myValueObj); →自java自动包装整数基元。