Как я могу разобрать этот ответ на ArrayList
. У меня есть массив иерархии, который содержит список объектов. В каждом объекте. Когда я получаю тип «группа», будет JSONArray
как «содержимое». Внутри JSONArray
я могу получить n объектов no.of. Каждый объект может содержать тип «группа».
Как разобрать и сохранить в ArrayList
.
hierarchy:
[
{
"id":"5fd1b4384f5ee9964099b6b0",
"name":"Dev_5 Category Group `",
"type":"group",
"contents":[
{
"id":"5fd1b4384f5ee9964099b6af",
"name":"Dev_5 Parent Category Group 1",
"type":"group",
"contents":[
{
"id":"5fd1b567505ee9af3a7a65c8",
"name":"Dev_5 Parent Category Group 2",
"type":"group",
"contents":[
{
"id":"5fd1b4384f5ee9964099b6b1",
"type":"category"
}
],
"desc":"",
"image":""
}
],
"desc":"",
"image":""
},
{
"id":"5fd1b57b4f5ee9114599b679",
"type":"category"
}
],
"desc":"",
"image":""
},
{
----
},
{
---
}
]
Код
for (int i = 0; i < hierarchyArray.length(); i++)
{
hierarchyItemList.clear();
JSONObject obj = hierarchyArray.optJSONObject(i);
JSONArray contentArray = obj.optJSONArray("contents");
HierarchyItem item = new HierarchyItem();
item.setId(obj.optString("id"));
item.setType(obj.optString("type"));
item.setGroupName(obj.optString("name"));
if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null &&
contentArray.length() > 0) {
hierarchyItemList.clear();
for (int j = 0; j < contentArray.length(); j++)
{
hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j)));
}
item.setContentList(hierarchyItemList);
}
if (obj.optString("type").equalsIgnoreCase("category") ||
(obj.optString("type").equalsIgnoreCase("group") && contentArray != null &&
contentArray.length() > 0)) {
itemList.add(item);
}
}
private static HierarchyItem hierarchyJSON(JSONObject obj) {
HierarchyItem item = new HierarchyItem();
item.setId(obj.optString("id"));
item.setType(obj.optString("type"));
item.setGroupName(obj.optString("name"));
JSONArray contentArray = obj.optJSONArray("contents");
List<HierarchyItem> hierarchyItemList = new ArrayList<>();
if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && contentArray.length() > 0) {
hierarchyItemList.clear();
for (int j = 0; j < contentArray.length(); j++) {
hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j)));
}
item.setContentList(hierarchyItemList);
}
return item;
}
Используя приведенный выше код, последний элемент обновляется до всех элементов в ArrayList
. Как это решить.
Заранее спасибо.
Если иерархияItemList является вашим списком результатов, вы не должны очищать его в нескольких местах, а только в самом начале.
Вот очищенная версия
public class JsonDemo {
public static void main(String[] args) throws Exception {
String jsonString = new String(Files.readAllBytes(Paths.get("test.json")), StandardCharsets.UTF_8);
JSONArray hierarchyJsonArray = new JSONArray(jsonString);
List<HierarchyItem> hierarchyItemList = new ArrayList<>();
for(int i = 0; i < hierarchyJsonArray.length(); i++) {
HierarchyItem hierarchyItem = parseItem(hierarchyJsonArray.getJSONObject(i));
hierarchyItemList.add(hierarchyItem);
}
}
private static HierarchyItem parseItem(JSONObject jsonObject) {
HierarchyItem hierarchyItem = new HierarchyItem();
hierarchyItem.id = jsonObject.optString("id", "");
hierarchyItem.type = jsonObject.optString("type", "");
hierarchyItem.name = jsonObject.optString("name", "");
hierarchyItem.desc = jsonObject.optString("desc", "");
hierarchyItem.image = jsonObject.optString("image", "");
// not even checking for type=group, if there is a contents array, parse it
JSONArray contentsArray = jsonObject.optJSONArray("contents");
if (contentsArray != null) {
for(int i = 0; i < contentsArray.length(); i++) {
// recursive call
HierarchyItem childItem = parseItem(contentsArray.getJSONObject(i));
hierarchyItem.contents.add(childItem);
}
}
return hierarchyItem;
}
}
class HierarchyItem {
public String id = "";
public String type = "";
public String name = "";
public String desc = "";
public String image = "";
public List<HierarchyItem> contents = new ArrayList<>();
}
test.json:
[
{
"id": "5fd1b4384f5ee9964099b6b0",
"name": "Dev_5 Category Group `",
"type": "group",
"contents": [
{
"id": "5fd1b4384f5ee9964099b6af",
"name": "Dev_5 Parent Category Group 1",
"type": "group",
"contents": [
{
"id": "5fd1b567505ee9af3a7a65c8",
"name": "Dev_5 Parent Category Group 2",
"type": "group",
"contents": [
{
"id": "5fd1b4384f5ee9964099b6b1",
"type": "category"
}
],
"desc": "",
"image": ""
}
],
"desc": "",
"image": ""
},
{
"id": "5fd1b57b4f5ee9114599b679",
"type": "category"
}
],
"desc": "",
"image": ""
},
{
"id": "id2",
"type": "category"
},
{
"id": "id3",
"type": "category"
}
]
Да? Я даже пометил рекурсивный вызов комментарием.
Хм, может быть, вы думали, что я прокомментировал это. Позвольте мне изменить это.
Позвольте мне проверить это @Reto
Вы очищали список значений в каждом цикле, поэтому существующие данные будут очищены, а новые значения обновлены в списке, поскольку вы использовали цикл рекурсии. Я удалил clear() для значения списка и снова инициализировал в начале цикла. Это решит вашу проблему.
for (int i = 0; i < hierarchyArray.length(); i++)
{
//hierarchyItemList.clear(); --> Remove this clear() method, it will clear your existing values
JSONObject obj = hierarchyArray.optJSONObject(i);
JSONArray contentArray = obj.optJSONArray("contents");
HierarchyItem item = new HierarchyItem();
item.setId(obj.optString("id"));
item.setType(obj.optString("type"));
item.setGroupName(obj.optString("name"));
if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null &&
contentArray.length() > 0) {
//hierarchyItemList.clear();
hierarchyItemList = new ArrayList<>(); // instead of clear the list, initialize it as new list, then it will keep existing list values and load new data in new list
for (int j = 0; j < contentArray.length(); j++)
{
hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j)));
}
item.setContentList(hierarchyItemList);
}
if (obj.optString("type").equalsIgnoreCase("category") ||
(obj.optString("type").equalsIgnoreCase("group") && contentArray != null &&
contentArray.length() > 0)) {
itemList.add(item);
}
}
private static HierarchyItem hierarchyJSON(JSONObject obj) {
HierarchyItem item = new HierarchyItem();
item.setId(obj.optString("id"));
item.setType(obj.optString("type"));
item.setGroupName(obj.optString("name"));
JSONArray contentArray = obj.optJSONArray("contents");
List<HierarchyItem> hierarchyItemList = new ArrayList<>();
if (obj.optString("type").equalsIgnoreCase("group") && contentArray != null && contentArray.length() > 0) {
hierarchyItemList.clear();
for (int j = 0; j < contentArray.length(); j++) {
hierarchyItemList.add(MenuJSON.hierarchyJSON(contentArray.optJSONObject(j)));
}
item.setContentList(hierarchyItemList);
}
return item;
}
Мне нужен рекурсивный вызов, потому что этот идентификатор "5fd1b4384f5ee9964099b6b1" объекта также может содержать тип: "группа". Это проблема. Это может быть до n время.