Android LinkedHashMap反序列化为HashMap,导致CCE错误
我试图在活动之间传递一个序列化的LinkedHashMap,当我反序列化对象时会得到一个混乱的结果/错误 我按如下方式序列化该对象:Android LinkedHashMap反序列化为HashMap,导致CCE错误,android,serialization,classcastexception,linkedhashmap,Android,Serialization,Classcastexception,Linkedhashmap,我试图在活动之间传递一个序列化的LinkedHashMap,当我反序列化对象时会得到一个混乱的结果/错误 我按如下方式序列化该对象: Bundle exDetails = new Bundle(); LinkedHashMap<String, Exercise> exMap = new LinkedHashMap<String, Exercise (workout.getExercises()); exDetails.putString(WO
Bundle exDetails = new Bundle();
LinkedHashMap<String, Exercise> exMap = new LinkedHashMap<String,
Exercise (workout.getExercises());
exDetails.putString(WORKOUTNAME, workout.getWorkoutName());
exDetails.putSerializable(workout.getWorkoutName(), exMap);
iComplete.putExtra("wName", exDetails);
startActivity(iComplete);
在最后一行。我已经用调试器验证了bundle(在第二个活动中)包含一个HashMap,而不是LinkedHashMap(我假设它应该包含)。我还应该提到,我需要维护条目添加到映射的顺序,因此使用LinkedHashMap。条目最终被打印出来,并且顺序对于输出非常重要
问题:
我是否特别做错了什么,或者这个问题是由于LinkedHashMap的序列化错误造成的?我注意到一些类似的线程,它们似乎在说这是一些Map实现的一个持续问题。但是他们没有直接回答我的问题
如果是后者,是否有一个不太高级的解决方法(我不远超过初学者水平,但我愿意尝试大多数事情),或者我需要咬紧牙关,做LinkedHashMap以外的工作
另外,我试图包含所有相关内容,但如果我遗漏了任何重要内容,我可以添加更多代码。我采用了不同的方法:将任何(类型的)映射序列化为2个ArrayList:一个包含键,另一个包含值。这样,映射条目的顺序(在LinkedHashMap中很重要)就得以保持 每个键/值都实现可序列化。如果您确定只需要字符串或一种特定类型的映射,那么将下面的通用代码转换为所需的场景应该非常容易,这也简化了复杂性 映射->2个阵列列表:
公共静态对ConvertMapToArray(@NonNull Map){
最终设置条目=map.entrySet();
final int size=entries.size();
最终ArrayList键=新ArrayList(大小);
最终ArrayList值=新ArrayList(大小);
对于(Map.Entry:entries){
key.add(entry.getKey());
add(entry.getValue());
}
返回新的对(键、值);
}
2 ArrayList->特定类型的映射
公共静态映射转换器ArrayStomap(@NonNull ArrayList keys、@NonNull ArrayList values、@NonNull classi)我的代码已经正常工作了15周。突然,我不知从哪里冒出了这个异常。Parcelable也无缘无故地崩溃了。我猜他们在某处销毁了一些代码。我也遇到了同样的问题,在测试代码后,这个错误开始出现在android 5.0或更高版本中。当通过捆绑包进行序列化/反序列化时,我必须实现一种类似于android的变通方法,将LInkedHashMap
转换为Hashmap
。有关更多血淋淋的详细信息,请参阅我对这个问题和链接问题的回答:
Bundle exDetails = getIntent().getBundleExtra("wName");
workoutName = exDetails.getString(WORKOUTNAME);
Serializable eData = exDetails.getSerializable(workoutName);
ex = new LinkedHashMap<String, Exercise>();
ex = (LinkedHashMap<String, Exercise>) eData;
java.lang.ClassCastException:java.util.HashMap cannot be
cast to java.util.LinkedHashMap
public static <K extends Serializable, V extends Serializable> Pair<ArrayList<K>, ArrayList<V>> convertMapToArrays(@NonNull Map<K, V> map) {
final Set<Map.Entry<K, V>> entries = map.entrySet();
final int size = entries.size();
final ArrayList<K> keys = new ArrayList<>(size);
final ArrayList<V> values = new ArrayList<>(size);
for (Map.Entry<K, V> entry : entries) {
keys.add(entry.getKey());
values.add(entry.getValue());
}
return new Pair<>(keys, values);
}
public static <K extends Serializable, V extends Serializable> Map<K, V> convertArraysToMap(@NonNull ArrayList<K> keys, @NonNull ArrayList<V> values, @NonNull Class<? extends Map<K, V>> mapClass) {
if (keys.size() != values.size()) {
throw new RuntimeException("keys and values must have the same number of elements");
}
final int size = keys.size();
Map<K, V> map;
try {
final Constructor<? extends Map<K, V>> constructor = mapClass.getConstructor(Integer.TYPE);
map = constructor.newInstance(size);
} catch (Exception nse) {
throw new RuntimeException("Map constructor that accepts the initial capacity not found.");
}
for (int i = 0; i < size; i++) {
final K key = keys.get(i);
final V value = values.get(i);
map.put(key, value);
}
return map;
}
public static <K extends Serializable, V extends Serializable> void saveMapToBundleAsArrays(@NonNull Map<K, V> map, @NonNull String key, @NonNull Bundle bundle) {
final Pair<ArrayList<K>, ArrayList<V>> mapToArrays = convertMapToArrays(map);
final String keyForKeys = key + "_keys";
final String keyForValues = key + "_values";
bundle.putSerializable(keyForKeys, mapToArrays.first);
bundle.putSerializable(keyForValues, mapToArrays.second);
}
public static Map<Serializable, Serializable> loadMapFromBundle(@NonNull Bundle bundle, @NonNull String key, @NonNull Class<? extends Map<Serializable, Serializable>> mapClass) {
final String keyForKeys = key + "_keys";
final String keyForValues = key + "_values";
final ArrayList<Serializable> keys = (ArrayList<Serializable>) bundle.getSerializable(keyForKeys);
final ArrayList<Serializable> values = (ArrayList<Serializable>) bundle.getSerializable(keyForValues);
return convertArraysToMap(keys, values, mapClass);
}
saveMapToBundleAsArrays(mModelEvolution, KEY_MODEL_DATA, bundle);
Class<LinkedHashMap<Serializable, Serializable>> linkedHashMapClazz =
(Class<LinkedHashMap<Serializable, Serializable>>) new LinkedHashMap<String, String>().getClass();
mModelEvolution = (LinkedHashMap) ObjectUtils.loadMapFromBundle(bundle, KEY_MODEL_DATA, linkedHashMapClazz);