为什么系统在将我的 LinkedHashMap 作为 Serializable 传递到 Intent 中时自动将其转换为 HashMap?

Why is the system automatically converting my LinkedHashMap to HashMap while passing it in an Intent as a Serializable?

我得到

java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap

LinkedHashMap<String, String> dataHashMap = (LinkedHashMap<String, String>) intent.getSerializableExtra("tests.test.MyApp.A.EXTRA_KEY"); Activity B 的给定(相关部分)代码中


  1. 在片段 A 中,我进行了以下检查:

    Log.i(TAG, "THE TYPE OF THE MAP RETURNED FROM populateSelectedEntryList(selectedResultEntry) IS " + 
    populateSelectedEntryList(selectedResultEntry).getClass().getSimpleName()
    + ".");//******PRINTS LinkedHashMap**********************
    

其中 打印 LinkedHashMap

  1. 在Activity B中,我有以下检查:

    LinkedHashMap<String, String> dataHashMap = (LinkedHashMap<String, String>)intent.getSerializableExtra("tests.test.MyApp.A.EXTRA_KEY");//**********ClassCastException*****************
    

    其中 打印 HashMap


问题是为什么?为什么系统将我的 LinkedHashMap 转换为 HashMap。当 LinkedHashMap 作为 Serializable 在意图中传递时,我如何强制它继续成为 LinkedHashMap?

代码的相关部分:

在片段 A 中,

public class A extends Fragment {
  ...

  public void onListItemClick(...) { 
    Intent intent = new Intent(getActivity(), B.class);
    ...
    intent.putExtra("tests.test.MyApp.A.EXTRA_KEY", populateSelectedEntryList(selectedResultEntry));
    Log.i(TAG, "THE TYPE OF THE MAP RETURNED FROM populateSelectedEntryList(selectedResultEntry) IS "
 + populateSelectedEntryList(selectedResultEntry).getClass().getSimpleName() + ".");//******PRINTS LinkedHashMap**********************
    startActivity(intent);
  };

  ...

  private LinkedHashMap<String, String> populateSelectedEntryList(MyParser.Entry selectedResultEntry) {
    LinkedHashMap<String, String> selectedEntryMap = new LinkedHashMap<>();
    ...
    return selectedEntryMap;
  }
}

在ActivityB里面,

public class B extends FragmentActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
        ...
        Intent intent = getIntent();
        LinkedHashMap<String, String> dataHashMap = (LinkedHashMap<String, String>) intent.getSerializableExtra("tests.test.MyApp.A.EXTRA_KEY");
  } //**********ClassCastException*****************
  ...
}

如果顺序不重要,请使用返回的 HashMap 重新创建 LinkedHashMap:

LinkedHashMap<String, String> dataHashMap = new LinkedHashMap(intent.getSerializableExtra("tests.test.MyApp.A.EXTRA_KEY"));

这里给出了解释:LinkedList put into Intent extra gets recast to ArrayList when retrieving in next activity

如果你想恢复一个LinkedList,或者一个Map,其中键的顺序不重要,你可以使用@schtever 的解决方案。如果你想恢复一个 LinkedHashMap 或一个 TreeMap 并且键的顺序 重要的,那就有点棘手了。

一个可能的解决方案是将 Map 转换为一对 List,如下所示:

活动 1:

public class Activity1 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Map<Integer, String> map = new LinkedHashMap<Integer, String>();
        map.put(1, "ONE");
        map.put(2, "TWO");
        map.put(3, "THREE");

        ArrayList<Integer> keys = new ArrayList<Integer>();
        ArrayList<String> values = new ArrayList<String>();
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            keys.add(entry.getKey());
            values.add(entry.getValue());
        }

        Intent intent = new Intent(this, Activity2.class);
        intent.putExtra("KEYS", keys);
        intent.putExtra("VALUES", values);

        startActivity(intent);
    }
}

活动 2:

public class Activity2 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        List<Integer> keys = (List<Integer>) intent.getSerializableExtra("KEYS");
        List<String> values = (List<String>) intent.getSerializableExtra("VALUES");

        Map<Integer, String> map = new LinkedHashMap<Integer, String>();
        for (int i = 0, n = keys.size(); i < n; i++)
            map.put(keys.get(i), values.get(i));

        Log.i("Activity2",  "" + map);
    }
}

这有点乱七八糟,而且非常冗长,但它确实有效。我很想知道是否有更好的解决方案。