Apache Ignite序列化/反序列化与字段反序列化的顺序有关。我需要在Ignite缓存中放置一个“b”实例,如下所示:
public class A {
private final String name;
public A(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class B extends A {
private Map<B, String> mapOfB;
public B(String name) {
super(name);
mapOfB = new HashMap<>();
}
public void addB(B newB, String someString) {
mapOfB.put(newB, someString);
}
public Map<B, String> getMap() {
return mapOfB;
}
@Override
public boolean equals(Object obj) {
if( obj != null && obj instanceof B) {
if(this.getName() == null && ((B) obj).getName() == null && this == obj) {
return true;
} else if(this.getName().equals(((B) obj).getName())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return this.getName()==null? System.identityHashCode(this):this.getName().hashCode();
}
}
如果我运行以下代码:
public static void main(String[] args) {
// write your code here
B b1 = new B("first");
b1.addB(b1, "some first string");
B b2 = new B("second");
b1.addB(b2, "some second string");
// init Ignite configuration
// force java.util.Hashtable to be binary serialized,
// it prevents infinite recursion and other problems
// occurring with the Optimized Serializer
IgniteConfiguration cfg = new IgniteConfiguration();
BinaryConfiguration binConf = new BinaryConfiguration();
Collection<String> binClassNames = new LinkedList<>();
binClassNames.add("java.util.Hashtable");
binConf.setClassNames(binClassNames);
cfg.setBinaryConfiguration(binConf);
Ignition.start(cfg);
// put b1 in cache
IgniteCache cache = Ignition.ignite().getOrCreateCache("MyCache");
cache.put(b1.hashCode(), b1);
//get b1 from cache
B b1FromCache= (B) cache.get(b1.hashCode());
// print map values
System.out.println("b1 map value: " + b1.getMap().get(b1));
System.out.println("b1 from cache map value: " + b1FromCache.getMap().get(b1));
}
b1来自缓存映射值:null
问题是子字段在父字段之前被反序列化,因此当Ignite反序列化B时,它首先创建一个空的B对象(带有null“name”和“mapofb”),然后尝试反序列化mapofb。它创建Hashtable,然后反序列化它包含的每个对象来填充它。
对于上面示例中的b2,没有问题,因为当它被反序列化时,还不存在对b2的引用,所以创建了一个新的b2对象,填充了b2字段(包括“name”字段),然后用正确的哈希将它添加到Hashmap中。
我无法更改A和B类以及这些对象的创建方式(如何填充Hashmap,...)因此必须通过改变序列化来解决。有没有一个简单的方法可以做到这一点?
备注:实际代码要复杂得多,may类介于实际B和HashMap之间。
你对这种行为的原因是正确的。Mapofb
字段在name
字段之前被反序列化,而hashcode()
依赖于该名称。并且b
的字段在作为键放入映射后会发生更改,因此是hashcode
更改。
我建议您更改您的数据模型,但既然您不能,这里有另一个选择...OptimizedMarshaller
似乎在映射方面没有问题,因为它使用了简单的Java序列化。但是您不能使用BinaryObject抽象和其他一些特性。以下是如何启用OptimizedMarshaller:
OptimizedMarshaller marshaller = new OptimizedMarshaller();
cfg.setMarshaller(marshaller);
如果存储的值不实现serializable
接口,则可能需要对其进行适当配置:
marshaller.setRequireSerializable(false);
但是请注意,禁用RequireSerializable
标志可能会以负面的方式影响序列化性能。
以下代码导致此异常: 所以问题是:如何在GSON序列化和反序列化的泛型HashMap中获得正确的实例?
我有一个有内部地图的POJO。我想将它从JSON反序列化为HashMap,但Jackson将JSON的内部映射反序列化为LinkedHashMap。我可以通过将映射的类型从“Map”更改为“HashMap”来强制它使用HashMap,但我想知道是否有方法告诉Jackson将反序列化为Map的特定实现? 这里是JSON: 和转换类: 如何使用ObjectMapper:
我试图使用Google的Gson库在Java中序列化和反序列化一个HashMap。我希望序列化这里所示的hashmap,将其保存到一个文件中,然后在以后的阶段从一个文件中读取并反序列化它。 HashMap如下所示 反序列化类的反序列化逻辑,以及我目前基于Web上找到的示例实现的对象类。IS: 下面是在test函数中调用的序列化和反序列化代码。测试函数序列化上面HashMap的一个对象,创建一个字符
嗨,我正在尝试学习hashcode()和equals()方法的目的。我尝试了以下程序。 输出: 我有两个疑问: 1) 我认为HashMap将包含一个条目,因为两个对象(ob1和ob2)的hascode是相同的。有人能解释为什么HashMap中有两个条目吗? 2)为什么返回false?
ClassCastException:com.google.gson.internal.LinkedTreeMap不能强制转换为java.util.HashMap 提前谢了。
为了确保在我的RESTful web服务中来回发送的数据不冗余,每个嵌套对象都只序列化了它的ID(消息的用户只序列化了用户ID,因为客户端和服务器都已经知道用户的所有详细信息)。 序列化工作正常,产生以下效果: 问题:反序列化不会生成仅具有其ID的嵌套对象。生成的反序列化嵌套对象为空。 以下是前面提到的消息和用户对象。序列化“策略”是从此处指定的第三个选项中使用的:如何仅序列化Jackson的子级