Android HashMap у комплекті?


90

android.os.MessageВикористовує Bundleдля відправки з його SendMessage-методом. Отже, чи можна поставити HashMapвсередині a Bundle?


java та android для початківців 8) thnx для всіх!
Marcus Toepper

Прийміть будь-яку відповідь, якщо ми вирішили вашу проблему. thx
AMerle


Відповіді:


164

спробувати як:

Bundle extras = new Bundle();
extras.putSerializable("HashMap",hashMap);
intent.putExtras(extras);

а в другому Діяльність

Bundle bundle = this.getIntent().getExtras();

if(bundle != null) {
   hashMap = bundle.getSerializable("HashMap");
}

оскільки Hashmap за замовчуванням реалізується, Serializableщоб ви могли передавати його за допомогою putSerializableBundle та отримувати інші дії за допомогоюgetSerializable


Я отримую помилку під час спроби серіалізувати зв’язану хеш-карту Parcel: неможливо визначити значення com.SGID.DataClass.InvalidSubscriptionReasonsData@41bd2b98
SweetWisher ツ

1
Чи можу я використовувати цей метод для об'єкта, який містить примітивний тип даних та список масивів іншого об'єкта ??
SweetWisher, ツ

3
Якщо у вас виникли проблеми, переконайтеся, що ви використовуєте HashMap, а не карту
Matthew

1
ви можете передати повернутий об’єкт, що серіалізується, у хеш-карту, дотримуючись наступних способів (HashMap <String, Integer>)
cammando

3
Це видасть попередження про неперевірений акторський склад. Чи безпечно це ігнорувати?
mitsest

12

Відповідно до документа , Hashmapреалізує Serializable, так що putSerializableя можу здогадатися. Ви спробували?


6

Зверніть увагу: якщо ви використовуєте AppCompatActivity, вам доведеться викликати метод protected void onSaveInstanceState(Bundle outState) {}( НЕ public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {} ).

Приклад коду ...

Зберегти карту:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("leftMaxima", leftMaxima);
    outState.putSerializable("rightMaxima", rightMaxima);
}

І отримайте його в onCreate:

if (savedInstanceState != null) {
    leftMaxima = (HashMap<Long, Float>) savedInstanceState.getSerializable("leftMaxima");
    rightMaxima = (HashMap<Long, Float>) savedInstanceState.getSerializable("rightMaxima");
}

Вибачте, якщо це якась дубльована відповідь - можливо, комусь це буде корисно. :)


4

Якщо ви хочете надіслати всі ключі в наборі, спробуйте

for(String key: map.keySet()){
    bundle.putStringExtra(key, map.get(key));
}

Мені цікаво, чи є якісь причини не робити цього? Я багато не використовував серіалізацію і ніколи не встановлював набори (нові для android), тому мені цікаво, чи це O (n), а додавання до набору ефективно O (1) чи ні. Якщо вони не відрізняються за вартістю, не розуміючи, чому ви заморочуєтесь із серіалізацією на іншій карті.
Капітан Принні

@CaptainPrinny, якщо карта не є єдиним, що ви зіставляєте з набором, ви можете клобувати значення, і ви не дізнаєтесь, чи був ключ частиною оригінальної карти або просто значенням, що зберігається в наборі.
Джейсон

1
  public static Bundle mapToBundle(Map<String, Object> data) throws Exception {
    Bundle bundle = new Bundle();
    for (Map.Entry<String, Object> entry : data.entrySet()) {
        if (entry.getValue() instanceof String)
            bundle.putString(entry.getKey(), (String) entry.getValue());
        else if (entry.getValue() instanceof Double) {
            bundle.putDouble(entry.getKey(), ((Double) entry.getValue()));
        } else if (entry.getValue() instanceof Integer) {
            bundle.putInt(entry.getKey(), (Integer) entry.getValue());
        } else if (entry.getValue() instanceof Float) {
            bundle.putFloat(entry.getKey(), ((Float) entry.getValue()));
        }
    }
    return bundle;
}

1

Я використовую свою реалізацію kotlin Parcelable для досягнення цього, і поки що це працює для мене. Це корисно, якщо ви хочете уникнути важкої серіалізації.

Також для того, щоб він працював, я рекомендую використовувати його з ними

Декларація

class ParcelableMap<K,V>(val map: MutableMap<K,V>) : Parcelable {
    constructor(parcel: Parcel) : this(parcel.readMap(LinkedHashMap<K,V>()))

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeMap(map)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<ParcelableMap<Any?,Any?>> {
        @JvmStatic
        override fun createFromParcel(parcel: Parcel): ParcelableMap<Any?,Any?> {
            return ParcelableMap(parcel)
        }
        @JvmStatic 
        override fun newArray(size: Int): Array<ParcelableMap<Any?,Any?>?> {
            return arrayOfNulls(size)
        }
    }

}

Використовуйте

писати

val map = LinkedHashMap<Int, String>()
val wrap = ParcelableMap<Int,String>(map)
Bundle().putParcelable("your_key", wrap)

читати

val bundle = fragment.arguments ?: Bundle()
val wrap = bundle.getParcelable<ParcelableMap<Int,String>>("your_key")
val map = wrap.map

Не забувайте, що якщо ваша карта K,Vне парцельована за замовчуванням, вона повинна реалізуватиParcelable


1
Ви намагалися скоротити за допомогою @Parcelize?
CoolMind

0

У Котліні:

hashMap = savedInstanceState?.getSerializable(ARG_HASH_MAP) as? HashMap<Int, ValueClass>

putSerializable(ARG_HASH_MAP, hashMap)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.