Cómo puede emitir un HashMap anidado en un ArrayList

Hay una ArrayList que ha anidado HashMaps. Es fácil obtener el valor de la HashMap padre, pero cuando intento obtener el valor de la HashMap anidada (child), obtengo ClassCastException. Este es un ejemplo de cómo se ve (similar a la publicación anterior):

ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>(); HashMap<String, Object> parentHash = new HashMap<String, Object>(); HashMap<String, String> childHash = new HashMap<String, String>(); childHash.put("child_id", "id") childHash.put("name", "first last"); childHash.put("sex", "man"); parentHash.put("parent_id", "id"); parentHash.put("name", "first last"); parentHash.put("sex", "woman"); parentHash.put("children", childHash); data.add(parentHash); 

Para emitir, utilizo el siguiente código (por desgracia, obtengo ClassCastException):

 Map<String, String> fetchedChildData = (Map<String, String>) data.get(position).get("children"); showAlert("Test", "Ok", (String) fetchedChildData.get("child_id")); 

¿Puede alguien decirme lo que estoy haciendo mal aquí?

Errorlist:

  04-03 17:34:01.640: W/dalvikvm(26248): threadid=1: thread exiting with uncaught exception (group=0x4001e578) 04-03 17:34:01.645: E/AndroidRuntime(26248): FATAL EXCEPTION: main 04-03 17:34:01.645: E/AndroidRuntime(26248): java.lang.ClassCastException: java.util.ArrayList 04-03 17:34:01.645: E/AndroidRuntime(26248): at com.on_d_mand.live_dashboard.EventListMenu$2.onItemClick(EventListMenu.java:265) 04-03 17:34:01.645: E/AndroidRuntime(26248): at android.widget.AdapterView.performItemClick(AdapterView.java:284) 04-03 17:34:01.645: E/AndroidRuntime(26248): at android.widget.ListView.performItemClick(ListView.java:3740) 04-03 17:34:01.645: E/AndroidRuntime(26248): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1992) 04-03 17:34:01.645: E/AndroidRuntime(26248): at android.os.Handler.handleCallback(Handler.java:587) 04-03 17:34:01.645: E/AndroidRuntime(26248): at android.os.Handler.dispatchMessage(Handler.java:92) 04-03 17:34:01.645: E/AndroidRuntime(26248): at android.os.Looper.loop(Looper.java:130) 04-03 17:34:01.645: E/AndroidRuntime(26248): at android.app.ActivityThread.main(ActivityThread.java:3691) 04-03 17:34:01.645: E/AndroidRuntime(26248): at java.lang.reflect.Method.invokeNative(Native Method) 04-03 17:34:01.645: E/AndroidRuntime(26248): at java.lang.reflect.Method.invoke(Method.java:507) 04-03 17:34:01.645: E/AndroidRuntime(26248): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912) 04-03 17:34:01.645: E/AndroidRuntime(26248): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670) 04-03 17:34:01.645: E/AndroidRuntime(26248): at dalvik.system.NativeStart.main(Native Method) 

Los objetos JSON que se representan como un "mapa" o "diccionario" no significan que usted debe representarlo igualmente en Java. ¡Los objetos están allí para este propósito!

Le sugiero que tenga un objeto que analizará el JSON asociado y se construirá a partir de él. Por ejemplo:

 public class User { public User() { name = ""; friends = new ArrayList<User>(); } /** Create a User from a JSON Object **/ public static User createFromJson(JSONObject json) { User u = new User(); // Read simple fields of the JSON object u.name = json.optString("name"); // Now recursively read other users from a "friend" property JSONArray jsonFriends = json.optJSONArray("friends"); for (int i=0; i<jsonFriends.length(); ++i) { // This is the next nested JSON Object JSONObject jsonFriend = jsonFriends.getJSONObject(i); // We convert it to a Java object User friend = User.createFromJson(jsonFriend); // And add it to our friend list u.friends.add(friend); } } private String name; private List<User> friends; } 

Esa clase leería muy bien un JSON tal como:

 { "name": "Joe", "friends": [ { "name": "Jack" }, { "name": "Rose" } ] } 

Su código funciona bien para mí en Java 6. Tal vez sea un error con Android Dalvik?

De todos modos, estoy de acuerdo en que deberías considerar crear tus propias clases ("Parent", "Child", etc) y usar el patrón de diseño compuesto , en lugar de usar colecciones dentro de colecciones dentro de colecciones.

 ArrayList<HashMap<String,Object>> data = new ArrayList<HashMap<String,Object>>(); HashMap<String, Object> parentHash = new HashMap<String, Object>(); HashMap<String, String> childHash = new HashMap<String, String>(); childHash.put("child_id", "id"); childHash.put("name", "first last"); childHash.put("sex", "man"); parentHash.put("parent_id", "id"); parentHash.put("name", "first last"); parentHash.put("sex", "woman"); parentHash.put("children", childHash); data.add(parentHash); Map<String, String> fetchedChildData = (Map<String, String>) data.get(0).get("children"); // prints: child_id=id System.out.println("child_id=" + fetchedChildData.get("child_id")); 

Esto debería funcionar:

 int position = 0; Map<String, Object> parent = data.get(position); Map<String, String> child = (Map<String, String>) parent.get("children"); 
  • Recibiendo la respuesta del eco del HTTP POST de un archivo de PHP (enviar los POSTS funciona muy bien, es el recibir que no puedo imaginar)
  • ¿Es posible compartir una imagen en Android mediante una URL de datos?
  • ¿Cómo se obtiene el "Nombre de dispositivo" definido por el usuario en android?
  • Cómo mostrar la selección del primer elemento en la vista de reciclador en android?
  • Detectar una excepción de entrada errónea
  • La vista de lista de Android enruta contenido hasta un tamaño determinado basado en el tamaño de pie de página
  • Xamarin .jar binding - 'Bitmap no se pudo encontrar'
  • Problema en la lectura de la palabra francesa desde el archivo de texto en java / android
  • Patrón de WeakReference / AsyncTask en android
  • Uso de HTML en el cuadro de diálogo de alerta de Android
  • XPath.Evaluar el rendimiento se ralentiza (absurdamente) en varias llamadas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.